jb's Blog


"behold the turtle, he only makes progress when he sticks his neck out"

SQL Server 2008 SP1 Released

tag icon Tagged as News, SQL Server

Quick news for the day, SP1 for SQL Server 2008 has been released and you can download it from here.

As with most service packs, its a roll up of all of the hot-fixes since RTM. There is nothing major in terms of new functionality, mainly just enhancements to the installation/un-installation process and Report Builder 2.0 which was initially shipped OOB.

Read more about it on the Data Platform team’s blog.



ASP.NET MVC now open source!

tag icon Tagged as MVC, News

In a quick bit of news, Scott Guthrie has posted an announcement declaring that the code for ASP.NET MVC has now been officially open sourced under the MS-Pl license.

Read more about it on the Gu’s blog and if you are looking to grab said source, then you can get it from here :)

Nice work guys – we appreciate it! :)



An interesting sample with IronRuby and LightSpeed

tag icon Tagged as LightSpeed, MVC, Ruby

Ivan Porto Carrero (you may know him as IvanPC ;)) tweeted about some interesting work he is doing in building out a sample with IronRuby no doubt as part of his upcoming book on IronRuby, ASP.NET MVC and LightSpeed. Its been a while since I checked in on IronRuby, but having a skim over the source it looks like its coming along pretty well.

You can check out what he is doing over at Github – and in particular if you are interesting in using LightSpeed with IronRuby – great work Ivan! :)



MVC and LightSpeed – Part 4 – Model Binding

tag icon Tagged as LightSpeed, MVC, jQuery

In our earlier instalment we started getting under way with our ASP.NET MVC site for the Film Festival and got our home page working by binding to our LightSpeed entities. Now we should look at what is involved with handling submission of a form where the target is a LightSpeed entity.

Setting up our Action

For this, I want to set up an admin form which we can use to create a new film. We wont concern ourselves too much with the UI here, but rather we are interested in how we can easily map our form data back to an entity and handle validation concerns.

Shot017

Here is the associated View action code:

    public ActionResult New()
    {
      var film = new Film() { Title = "New Film", Year = DateTime.Now.Year };
 
      return New(film);
    }
 
    [NonAction]
    public ActionResult New(Film film)
    {
      return View("New", film);
    }

Next I want to set up my Create() action which will take the POST from this form and will create me a new film.

There are several ways we could pass in input, either by named parameters, through a FormCollection object or through a Film instance directly – well that last option sounds ideal, particularly for when we come to write some tests, so how do I go about that? Surely the form knows nothing about my object structure, does MVC? How does this work?

Cue the Model Binder

If you have used another MVC framework such as Monorail, you will know that it provides some nice data binding support to allow you to map an inbound form collection to an object instance, or reconstruct a graph of objects. MVC provides us the same capabilities through Model Binders.

Model Binders are classes which provide the specifics of how to map a form collection (a bag of key/value pairs) back to a real entity. Out of the box there is a DefaultModelBinder available which does a blind property mapping.

I am going to create a specific model binder for LightSpeed entities which provide some specific understanding of how we want to perform this mapping.

The method we need to implement for IModelBinder is the BindModel method, in this call I am going to unbind all of the value fields on a LightSpeed entity based on the convention that the form parameter will map to a property name on my entity. If not, then we will ignore it. We could also possibly extend this by providing support for Included/Excluded properties which is something the DefaultModelBinder provides.

You can see the code for this class here: https://code.mindscape.co.nz/repos/LightSpeed/Mvc/Trunk/Src/Mindscape.LightSpeed.Mvc/Binding/EntityModelBinder.cs

To use this model binder, we will call EntityModelBinder.Register() from inside our Global.asax start up code – in turn this makes assignments to the ModelBinders.Binders collection.

Once these have been registered, the binding is handled automatically, as ASP.NET MVC sees a parameter and looks up if there is a specific model binder for that type, in the case of an entity there will be, and then it calls to BindModel() on that model binder to do the work.

So if we take this signature for our POST action -  public ActionResult Create(Film film) - then the result will be an instantiated Film entity.

Handling Validation

How do we determine if there are any errors with the inbound object? Well we can leverage LightSpeed’s baked in validation attributes to provide the answer.

When we first created the definition of our domain model, the LightSpeed Designer automatically assigned appropriate validations on the model based on the database definition – e.g.

  [Serializable]
  [System.CodeDom.Compiler.GeneratedCode("LightSpeedModelGenerator", "1.0.0.0")]
  public partial class Film : Entity
  {
    #region Fields
 
    [ValidatePresence]
    [ValidateLength(0, 255)]
    private string _title;
    [ValidatePresence]
    private string _description;

The ValidatePresence and ValidateLength attributes are specifying validation concerns.

In our model binder you will notice that after we have unbound the entity we call .IsValid – this triggers LightSpeed to validate the entity (it automatically does this when trying to save as well, so you would get an exception if you tried to save an invalid entity). We can then bind any errors it finds into the ModelState.

      if (!entity.IsValid)
      {
        foreach (var error in entity.Errors)
        {
          bindingContext.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
        }
      }

So applying this, and then pushing Create on my form (silly me) we get this

Shot018

Excellent! We can get the nice little validation summary by leveraging a method on the HtmlHelper class called ShowValidationSummary – I have set it up like this:

<!--Html.ValidationSummary("There were some errors with your submission..")-->

And my controller code now looks like this:

    public ActionResult Create(Film film)
    {
      if (!ModelState.IsValid)
      {
        return New(film);
      }
 
      UnitOfWork.Add(film);
      UnitOfWork.SaveChanges();
 
      return RedirectToAction("Index", "Home");
    }

You can see that we are just testing ModelState.IsValid to confirm if any binding errors occurred. We could also simply check film.IsValid to achieve the same thing.

This is not the only way to handle ASP.NET MVC validation, and I would point you to some of the posts David Hayden has put out on the facilities you have at your disposal along with the tutorials on the ASP.NET MVC site.

So server side validation plug’s in nicely with LightSpeed and its validation – what about if we also want some client side validation? Well thanks to a great suggestion by Justin Thirkell we can leverage jQuery and a validation plugin here along with xVal to make this nice and easy.

xVal

From Steve Sanderson’s blog: “xVal lets you link up your choice of server-side validation mechanism with your choice of client-side validation library. It guides you to fit them both into ASP.NET MVC conventions, so everything plays nicely with model binding and errors registered in ModelState”. Read more.

It is nice and flexible allowing a many to many mapping of validations as follows:

Great – so all we need to do is teach it about LightSpeed’s validation attributes.

To do this, I have used some code Justin sent through which adds a custom IRulesProvider, you can see what this looks like here: https://code.mindscape.co.nz/repos/LightSpeed/Mvc/Trunk/Src/Mindscape.LightSpeed.Mvc/Validation/LightSpeedXValRulesProvider.cs

Adding this in to my project means I need to add the following to my startup code in Global:

xVal.ActiveRuleProviders.Providers.Add(new LightSpeedXValRulesProvider());

and then a declaration on my page for xVal to apply its validation against a Film:”

<!--Html.ClientSideValidation<FilmFestival.Model.Film>()-->

and the result is I have client side validation!

Shot019

Playing along at home?

Here is the code and associated database setup script (remember to create a database called FilmFestival and run the scripts under the context of that database first or use the Build.cmd script) to cover what we have done so far. Also remember to download and install LightSpeed.

We are now also leveraging some of the community code project – Mindscape.LightSpeed.Mvc – this has been included in the Lib folder, or you can grab it independently from here.

Download FilmFestival2009_Part4.zip (94KB)

Ok - What’s next?

Next we should build out some of the remaining functionality which will probably bring up the topics of routing and some more jQuery :)



Check out some cool local Silverlight innovation

tag icon Tagged as News, Silverlight

I was cranking some table tennis with Tokes, OJ and Lee from Intergen today at lunch and Tokes mentioned that he had just pushed out a great new Silverlight app timed with MIX 09 so I thought I should check it out :)

It’s a Silverlight based audio book reader and was developed in conjunction with Microsoft for The Royal New Zealand Foundation for the Blind. You can check out Tokes’s post on this and then have a look at the reader itself.

Awesome work guys!



MVC and LightSpeed – Part 3 – Setting up the Site

tag icon Tagged as LightSpeed, MVC, jQuery

In our earlier instalments we set up our domain model for the Film Festival as well as a unit test project (currently for the model, but we will extend that for the web site soon enough..). Now its time to create our MVC site.

Create the Web

First step is to set up an ASP.NET MVC site instance called “Web”, this is easily achieved using the VS template if you have it installed.

Shot013

By default, the template includes quite a few things I don’t really care for such as an out of the box set of styles and some of the Microsoft AJAX scripts – I get away with just jQuery. You will notice that the current latest version of jQuery is installed with the RTM templates (1.3.2), however this will soon be updated so make sure you check for these on jQuery.com regularly enough. The focus of this current line (1.3.x) seems to be focused on really tuning the performance of the library so you will likely benefit from upgrades :)

Here is what my structure looks like at the end of some quick culling..

Shot014

I have obviously added in references to the Model project and LightSpeed, and I have added the Web project as a reference for our UnitTests.

Cue the pre-canned stuff

Given that I am updating my existing FilmFestival site – I do already have some of the creative taken care of :)  Cue the one I baked earlier, and our site now looks like this – I have included an existing style sheet and images, and then modified Site.Master and Views/Home/Index.aspx to make this happen.

Our site is now taking shape visually which is always motivating I find..

Shot015

What we now want to do is set up the home page so that it displays a list of our locations, a sample selection of films on the side bar and for it to display the first film as our “feature film” showing its photo and the name of the film.

Controllers

The process logic for our web application is executed in the Controller actions. The paradigm with MVC is we set up a routing table which will map incoming requests to controller actions based on the URL which has been requested.

The default routing table included with our MVC site is this:

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
      routes.MapRoute(
          "Default",                                              // Route name
          "{controller}/{action}/{id}",                           // URL with parameters
          new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
      );
 
    }

You can see that currently our HomeController::Index() action is pretty thin – nothing wrong with that, Thin Controller / Thick Model is generally what we are aiming for, however what we do need it to do is to fetch us a list of locations and some films, and to do that we need to fetch them through our LightSpeed unit of work.

Managing the LightSpeed Unit of Work on a Per Request basis

When using LightSpeed the UnitOfWork manages interactions with your entities inside a scope, usually about the size of a business transaction. On the web, your transaction is likely to be the scope of a single request so ideally we want a unit of work to be set up at the beginning of a request and then to be disposed at the end. We can set up this approach using the PerRequestUnitOfWorkScope<TUnitOfWork> class, which is an implementation of UnitOfWorkScopeBase<TUnitOfWork> and will hold us an instance of TUnitOfWork which in our case will be our strongly typed UnitOfWork class which was generated for us when we set up the domain model earlier and has the IQueryable properties for our entity collections making querying a bit easier through LINQ.

To help set this up, we are going to create a base controller class for our project called FilmFestivalController which implements Controller. All of our specific controllers such as HomeController will implement this.

Here is the code we are going to add:

    private const string UNIT_OF_WORK = "__UnitOfWork__";
    private UnitOfWorkScopeBase<FilmFestival.Model.UnitOfWork> _unitOfWorkScope;
 
    public UnitOfWorkScopeBase<FilmFestival.Model.UnitOfWork> UnitOfWorkScope
    {
      get
      {
        if (_unitOfWorkScope == null && System.Web.HttpContext.Current != null)
        {
          _unitOfWorkScope = System.Web.HttpContext.Current.Items[UNIT_OF_WORK] as PerRequestUnitOfWorkScope<FilmFestival.Model.UnitOfWork>;
        }
 
        if (_unitOfWorkScope == null)
        {
          _unitOfWorkScope = new PerRequestUnitOfWorkScope<FilmFestival.Model.UnitOfWork>(MvcApplication.LightSpeedDataContext);
 
          if (System.Web.HttpContext.Current != null)
          {
            System.Web.HttpContext.Current.Items[UNIT_OF_WORK] = _unitOfWorkScope;
          }
        }
 
        return _unitOfWorkScope;
      }
    }
 
    protected FilmFestival.Model.UnitOfWork UnitOfWork
    {
      get { return UnitOfWorkScope.Current; }
    }
 
    protected override void OnResultExecuted(ResultExecutedContext filterContext)
    {
      if (_unitOfWorkScope != null)
      {
        _unitOfWorkScope.Dispose();
      }
 
      base.OnResultExecuted(filterContext);
    }
 
    public new void Dispose()
    {
      if (_unitOfWorkScope != null)
      {
        _unitOfWorkScope.Dispose();
      }
 
      base.Dispose();
    }

Basically we are facilitating a Festival.Model.UnitOfWork property on our controllers which will be bound to the current unit of work for this request – otherwise one will be instantiated as required by calling .CreateUnitOfWork on the LightSpeedContext (gives context on how we are connecting to the underlying database) which is a static object we have declared in our Global.asax

internal static readonly LightSpeedContext<FilmFestival.Model.UnitOfWork> LightSpeedDataContext 
  = new LightSpeedContext<FilmFestival.Model.UnitOfWork>("default");

You can see that we also implement an override for OnResultExecuted which will fire once the ActionResult has been processed which disposes the unit of work.

If we take an approach of not passing entities through to the views where the unit of work may possibly be needed to reference lazy child collections and the like then we could dispose those earlier, however you may find it more sensible to allow yourself this convenience in your view – but be aware you may be generating additional database request (== costly).

Fetching what we need for the Home View

Getting information to the view can be done in one of two ways, either we can use the generic ViewData property bag – e.g. ViewData[“Key”] = value; or we can create a strongly typed ViewModel class which we pass in place of the generic ViewDataDictionary instance. I currently prefer the latter approach because it is a little clearer about what needs to be sent to the view and I also find myself re-using these view models across a number of views which can also be helpful. The downsides I have noticed so far is that often your ViewModel may be specific to the view, so you either end up with a large ViewModel which is being shared around but some properties are never set which means you possibly should just go back to the property bag :) YMMV so keep both options in mind.

So I want to quickly create a ViewModel for our Index action, nothing hard here, I create a class called HomePageViewModel.cs and put it under a ViewModels folder, it is going to look like this:

public class HomePageViewModel
{
  public IList<Film> Films { get; set; }
  public IList<Location> Locations { get; set; }
  public Film FeaturedFilm { get; set; }
}

We can fetch our data by modifying the Index() action as follows

IList<Film> films = UnitOfWork.Films.ToList().OrderBy(o => Guid.NewGuid()).Take(8).ToList();
 
HomePageViewModel model = new HomePageViewModel()
{
  Locations = UnitOfWork.Locations.ToList(),
  Films = films,
  FeaturedFilm = films[0]
};
 
return View(model);

You can see how we can use the IQueryable properties on UnitOfWork as entry points for our queries, you can use LINQ syntax to structure up a query to fetch your entities as required – for example my “random” selection fetches all Films into memory and then sorts them randomly using GUIDs and then selects the top 8 for display.

Applying this to the View

I am currently using the default WebFormViewEngine (ASP.NET Web Forms) for the views, so I have .aspx files to work with. One of the nice things about ASP.NET MVC is that I am not limited to just using web forms. If I dont like it I could use something like NHaml, which is currently my preferred view engine, however that is kind of a tangent so we will stick with web forms for now.

Firstly I want to use my typed view model, so I will declare a local variable on the form called Model to hold this

<% var Model = (Web.ViewModels.HomePageViewModel)ViewData.Model; %>

This is a bit naff – There undoubtedly is a better way but my ignorance in the WebFormViewEngine space has left me a bit naive here. With NHaml we have our typed models available so I wouldn’t need to declare this.

The next step is to expand out our view code to make use of the Model we have available to wire up our required entities for display. e.g.

        <h3>
          <a href="/films">Explore Films</a>
        </h3>
        <ul>
            <% 
              foreach (var film in Model.Films)
              {
            %>
              <li>
                <a href=<%= String.Concat("/film/", film.Id) %>>
                  <%= film.Title %>
                </a>
              </li>
            <%
              }
            %>
        </ul>

Easy enough. I am likely to want to refactor how those links are getting generated however because I know we can make use of some of the HtmlHelper utilities to generate these – we can refactor this once we have built out actions for these targets.

Look at the Home Page now

So with our model wired up, lets re-run our site – and here is what it now looks like

Shot016 

So that’s a great start, the only thing I probably want to add to this is a bit of Output caching to avoid generating unnecessary work on the server – we can do this easily in MVC by applying an [OutputCache(Duration=60, VaryByParam="")] attribute on the top of our Index action. How can we tell its working? Well previously the home page would likely display a new film after each refresh, now it does not. The [OutputCache] attribute is an example of an action filter, we will delve more into these at a later time.

Playing along at home?

Here is the code and associated database setup script (remember to create a database called FilmFestival and run the scripts under the context of that database first or use the Build.cmd script) to cover what we have done so far. Also remember to download and install LightSpeed.

Download FilmFestival2009_Part3.zip (538KB)

Ok - What’s next?

Next we can look at setting up a form where we want to unbind the data into a LightSpeed entity and flesh out some functions of the site a bit more.



ASP.NET MVC now released

tag icon Tagged as MVC, News

In case you haven’t heard the news already, ASP.NET MVC was officially launched as part of MIX 09 today and you can now grab it in either source or binary forms (or both if you are like me) :)

Check out the ASP.NET site for all the links and details you will need – I noticed they had a nice set of tutorials available as well so worth checking out :)

One of the other interesting tidbits to come out of the keynote this morning was Azure now supporting full trust deployments which will make life a lot easier for everyone. Great stuff!



ASP.NET and MVC – Part 2 – UnitTests for the Model

tag icon Tagged as LightSpeed, MVC, jQuery

In our earlier instalment we embarked on setting up an ASP.NET MVC using LightSpeed, jQuery, Ninject and NUnit and started by building up our domain model in LightSpeed.

So it is about time we moved on to setting up our UnitTests project and got underway but getting some initial tests in for our model. So lets get started..

Some minor tweaks since last time..

Before we get started, I should mention I have quickly tidied up some of the code from last time – namely I have renamed the namespaces for this solution to be FilmFestival.* rather than lacking a top level namespace as we did previously when we set up our Model project.

I have also updated the LightSpeed model to generate into the namespace FilmFestival.Model and not prefix the generated UnitOfWork so we can find it at FilmFestival.Model.UnitOfWork.

Shot009

You can do this in the entity designer by altering the Name and TargetNamespace properties accordingly.

One other tweak I had to make was to update the property definition for Cinema.GeoLocation to be a string rather than an object (which is what the LightSpeedDesigner see’s it as in SQL 2005 mode since the underlying SQL type is a SQL 2008 geography). If I was using the SqlServer2008 provider we could natively use the SqlGeography type on our LightSpeedEntity, but that isn’t released yet ;)

Back to the tests!

So first we need to set up a new project for our unit tests, I generally call this UnitTests (original is my middle name..), and we will start by adding references to our Model project, the LightSpeed assemblies and to NUnit.Framework which is what we will use for our testing. You could use XUnit, MBUnit, MSTest or whatever takes your fancy – I prefer NUnit for the time being :)

Shot010

The last reference I generally add is to Newtonsoft Utilities.NET which has some useful classes for testing entities. You should check this out in general as there is plenty of useful stuff in there, plus it was made by local ninja, crime fighting bat by night and occasional Supreme Commander victor James Newton-King :)

Managing Reference Assemblies

At this point we have started making use of some 3rd party assemblies, namely NUnit and Utilities. They may not be standard on other developers machines or on my build server, so I want to reference them from a relative path within my project structure. If you read my earlier post on project structure, you will know we should have a Lib folder for holding our reference assemblies together with the source for the project to make it more portable.

Setting up a TestFixture

The test fixture is your container for tests and allows the test framework (NUnit) to locate appropriate groups of tests to be executed. In a simple sense, what we would do is mark every class which contains tests up with a [TestFixture] attribute (found in NUnit.Framework) and that would be enough. Because we are generally likely to have common groups of tests separated across a number of files (e.g. 1 class for each model entities tests) I like to use base classes to help keep the common behaviour together.

So first off, lets provision a base TestFixture class.

  
[TestFixture]
public abstract class TestFixture    
{
    protected static LightSpeedContext&lt;Model.UnitOfWork&gt; _context;      
    public Model.UnitOfWork UnitOfWork { get; set; }
 
    static TestFixture()
    {        
      InitializeLightSpeed();
    } 
 
    public static void InitializeLightSpeed()
    {
      // TODO
    }
 
    private TransactionScope _transactionScope;
 
    [SetUp]
    public virtual void SetUp()
    { 
      _transactionScope = new TransactionScope();     
    }
 
    [TearDown]     
    public virtual void TearDown()     
    {    
      _transactionScope.Dispose();     
    }
  }

What this does is set up the framework for us to run transactional based tests against the database where the resulting transaction will always just be thrown away after each test execution – this is what we are doing with the TransactionScope in the [SetUp] and [TearDown] methods.

The last bit is we want to initialize LightSpeed. This can be done one of two ways, either from configuration or in code. For your standard applications we would recommend you use configuration, for tests, building up the context programatically is usually preferable.

So lets fill out the InitializeLightSpeed method as follows:

public static void InitializeLightSpeed()       
{         
  _context = new LightSpeedContext&lt;Model.UnitOfWork&gt;()         
  {           
    ConnectionString = @"server=localhost;database=FilmFestival;integrated security=sspi;",           
    Logger = new ConsoleLogger(),
    PluralizeTableNames = false         
  };
}

Hopefully thats obvious enough as to what we are doing here. The LightSpeedContext is effectively a factory which will instantiate us units of work which we will use to scope our interactions with the repository. For the test scenarios it will be one unit of work per test, so we can add a UnitOfWork = _context.CreateUnitOfWork(); call into the [SetUp] method to round this off.

Now whenever we access the property UnitOfWork from in our text fixtures, it will be instantiated and ready for us to do some work, and that work will always be rolled back at the end of the test regardless of what happens.

Setting up some Model Tests

Lets create some tests for our Cinema entity. For Entities, I generally have 3 stock tests (as below) before we add in anything specific to the behaviour of this entity. These tests are just there to validate we can find things and that the entities properties are at least all being checked for assignment using the ClassTester from Utilities.NET.

public class CinemaTests : TestFixture
{       
  [Test]
  public void FindOne()       
  {
      Cinema cinema = UnitOfWork.FindOne&lt;Cinema&gt;(300); 
 
      Assert.IsNotNull(cinema);       
  } 
 
  [Test]
  public void FindAll()       
  {
      Assert.AreEqual(12, UnitOfWork.Cinemas.Count());       
  } 
 
  [Test]
  public void Properties()       
  {
      ClassTester tester = new ClassTester(new Cinema());
      tester.IgnoredProperties.Add("EntityState");
      tester.TestProperties();       
  }
}

You can see we are using a mixture of LightSpeed’s query syntax (FindOne) and LINQ (UnitOfWork.Cinemas.Count()) in these tests. Generally if you are using .NET 3.5 you will be using LINQ as your primary syntax.

Oops, We need some Test Data

Ok run the tests up. And it fails. That’s good :) What are we missing? Oh yes, some test data. I have added in a Data.sql to our schema directory with some initial test data to cover our model so far, and one of the other things I like to add now is a little batch file to automate rebuilding things. You can have a look through both in the Schema folder in the attached code drop.

What else can we test?

In our earlier instalment we had added a helper property on to our Cinema which returned a parsed string with the co-ordinates of the Cinema’s location, so it would be good to validate our assumptions around its behaviour.

e.g.

    
  [Test]
  public void Coordinates()       
  {
      Cinema cinema = UnitOfWork.FindOne&lt;Cinema&gt;(300);
      Assert.AreEqual("-41.2947,174.7841", cinema.Coordinates); 
 
      cinema = new Cinema() { Name = "Foo" };
      Assert.AreEqual("0,0", cinema.Coordinates);       
  } 
 
    [Test]       
    public void CoordinatesAreZeroWhenGeoLocationIsNullOrEmpty()
    {         
      Cinema cinema = UnitOfWork.FindOne&lt;Cinema&gt;(300);
 
      cinema.GeoLocation = null; 
 
      Assert.AreEqual("0,0", cinema.Coordinates); 
 
      cinema = UnitOfWork.FindOne&lt;Cinema&gt;(300);
 
      cinema.GeoLocation = String.Empty; 
 
      Assert.AreEqual("0,0", cinema.Coordinates);       
    }

And so on..

Because your domain model should be playing a fairly important role in the application it is important to make sure it is well tested. I prefer using the ClassTester to cover the basics of assignment to catch any silly errors and then write specific tests for known behaviours. Your personal approach may vary, but look to achieve a fairly high level of coverage for your model.

I would also highly recommend TestDriven.NET or Resharper to give you IDE integration to execute tests via shortcut keys in scope of whatever you are currently working with (single test, test class, whole project, whole solution) which speeds things up quite a lot.

TestDriven FTW

Playing along at home?

Here is the code and associated database setup script (remember to create a database called FilmFestival and run the scripts under the context of that database first or use the Build.cmd script) to cover what we have done so far. Also remember to download and install LightSpeed.

Download FilmFestival2009_Part2.zip (94KB)

Ok - What’s next?

Next we are ready to get our MVC site itself underway, then we can build out some actual functionality.



Useful ASP.NET MVC Resource

tag icon Tagged as MVC

ScottGu has posted about a new sample ASP.NET MVC application which has been put together by some of the vocal members of the ASP.NET MVC team (Phil Haack, Scott Hanselman..) which forms part of their new book (also on the topic of ASP.NET MVC).

They have posted up a free PDF of part of the book which focused on getting started with ASP.NET MVC and building up the NerdDinner site – as well as having all the source code available on Codeplex for you to make use of.

Thanks guys!



Updates in the world of SQL Data Services

tag icon Tagged as SQL Server

If you have been interested in taking advantage of the cloud, then you will likely be interested in some news coming out of the SDS team. David Robinson has posted about some upcoming changes to SDS which brings on stream all of the SQL Server capabilities by allowing TDS (aka standard SQL Server protocol) access to connect to SDS from inside your Azure hosted application.

Full Relational Capabilities

So this brings on stream all of the standard SQL Server capabilities which most developers would be expecting and also really drops potential design constraints you might have been facing when looking at the much simpler ACE (Authority, Container, Entity) model which SDS previously offered.

IMHO this should really help drive adoption of Azure, and I’m hoping we will also see some tighter deployment capabilities getting released with the upcoming Azure CTP drops which will go a long way to allowing you to develop locally, deploy locally or deploy to the cloud without having to re-design the app to fit the environment. Good stuff!

So what about the ACE model?

From David’s post he suggests the ACE model will be discontinued over time – I suspect the Azure team will be keen enough to drop this as soon as is practical, but I believe if you still want to use the ACE model you can opt for the lower level Azure Table Storage approach. The other implication about the change is it would seem that the REST based API’s may also go away, or be replaced with Astoria based replacements sitting over SQL Server on Azure.

All in all a very promising move! It sounds like the first we will see of this will be around mid year, so we shall see how it all looks then. Of course we will be quite keen to get LightSpeed working well on the Azure hosting with this approach :)



jb's Blog