This post is over 6 months old. Some details, especially technical, may have changed.

ASP.NET MVC 3 Preview 1 First Look

[[posterous-content:6xLmqhke9CMHGNqiaUG7]] 

A much better read than the ramblings below:
http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx

So I had a chance to take ASP.NET MVC 3 Preview 1 out for a test drive today to see what was new and interesting.  For a Preview release it seems fairly solid - there is a lot of low level stuff introduced (new Interfaces etc) which is, I assume, going be used to add new features in Preview 2, 3, 4 whatever.  There is nothing MASSIVE per say in fact it really feels like the next logical step in the MVC roadmap rather than some crazy reimagining.  That's good by the way - backwards compatibility maintained and life goes on as normal.  The most obvious "issue" I have with this release is that it's NET4/VS2010 only which means if it came out tomorrow we'd probably not have the choice of making use of it due to the snails pace of the "enterprise".  Anyways enough preamble, down to the juicy stuff - what's this release giving us?

Razor

Preview 1 introduces Microsofts new ViewEngine, Razor, to the MVC world (WebMatrix aside).  Currently there is no syntax highlighting/intellisense for it but it'll still compile and generate views just fine.  I don't want to dive into Razor in this post but it's a weird syntax.  It's certainly feels much neater than the WebForms View Engine and for a weird reason it felt quite natural to use it - want to embed some serverside code?  Just type @ and you drop into serverside mode but with the advantage of actually still being able to embed HTML content without having to escape it.  The render just knows.  It's strange but good.

@inherits System.Web.Mvc.WebViewPage<Models.Person>
@{
    View.Title = "Home Page";
    LayoutPage = "~/Views/Shared/_Layout.cshtml";
}

<div>
    @Html.ValidationSummary()
    @{Html.EnableClientValidation();}
    @using(Html.BeginForm()){
        <p>Name:</p>
        @Html.TextBoxFor(p => p.Name)
        <div>@Html.ValidationMessageFor(p => p.Name)</div>
        <input type="submit" value="Submit"/>
    }
</div>

Read more here: http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx

On a side note when you create  a new view MVC 3 and VS2010 detects installed view engines so you can EASILY pick and choose which is very nice - though no ViewEngine currently supports this e.g.

[[posterous-content:Ryck0mqEkX92dSBGu1n4]]

Model Validation

There is some nice stuff in this area.  In MVC you where restricted to validating properties of a model (by default using data annotations) and if you wanted to validate entire models or perform validation in model scope (e.g. compare 2 fields) you had to write custom code.

MVC3 provides model-level validation in 2 ways,

1.       Using Validation Attributes

2.       Using the new data annotations interface IValidateObject

Validation attributes are the same attributes that the default validation strategy currently uses except you now have access to the model and ValidationResult has been tweaked to allow broken rules to be bound to multiple fields e.g.

public class PasswordsMustMatchAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(
        object value, ValidationContext validationContext)
    {
        var model = validationContext.ObjectInstance as Person;
        if (model.Password == model.PasswordConfirm)
        {
            return ValidationResult.Success;
        }

        return new ValidationResult(
            "Password and Password Confirmation must match",
            new string[] { "Password", "PasswordConfirm" });
    }
}

IValidateObject interface is the new way to provide validation of a Model object across all MS technologies (EntityFramework, DynamicData, Silverlight and ADO Data Services) and it behaves much better than the decoupled attribute stuff - at least in the preview.

If model implement the IValidateObject interface they are expected to implement the validate(ValidationContext context) method which returns an enumerable of ValidationResults.  The Person model in my sample app gives an example of this,

public class Person : IValidatableObject
{
    public string Name { get; set; }
    public string Nickname { get; set; }
    public string Password { get; set; }
    public string PasswordConfirm { get; set; }
    public int Age { get; set; }

    public IEnumerable<ValidationResult> Validate(
        ValidationContext validationContext)
    {
        if (Name.Equals(Nickname))
        {
            yield return new ValidationResult(
                "Name and Nickname cannot be the same",
                new string[] { "Name", "Nickname" });
        }
    }
}

Global Filters

More of a convenience than anything, global filters allow you to apply the same Action Filters to EVERY controller action within an application.  Useful for all tha AOP style stuff like logging etc.  Taking the new KDF Action Logger we can log every action invocation by pushing the attribute type into the global filters via global.asax like so,

GlobalFilters.Filters.Add(new LoggingFilter());

Thats it really.  Nice and convenient.

Json Model Binding

Typically model bindng is done through creating an new instance of the model and attempting to bind up properties against the names of the values submitted by the client.  This doesn't really work in the Ajax world because the body of a POST request is generally a single unnamed parameter which represents a JSON encoded string of the client request data.  In MVC2 we had to write custom binders to parse the string and bind to a model but in MVC3 this is provided automatically.  Again another nice to have.

Other stuff

·         Dynamic ViewModel  - Simply a dynamic bag allowing us to use ViewModel.SomeProperty vs ViewData["SomeProperty"]

·         New hooks for IoC/Dependency Injection through the lifecycle

·         New ways to expose Client Validation and Model Metadata which "should" allow an easier way to create a single point of validation that can be used across both client and server

·         New view results - HttpStatusCodeResult and Permanent Redirects

Summing up

MVC3 Preview 1 is a solid enough release but ultimately it seems to be a foundation, albeit a solid one.  Given the previous release schedule I expect another release within the next few months.  What can we expect for future releases?  See here.

Published in .NET on July 27, 2010