ASP.NET MVC V2 Preview 1 Released

The ASP.NET team just released the first public preview of ASP.NET MVC Version 2.  

Today’s preview works with .NET 3.5 SP1 and VS 2008, and can be installed side-by-side on the same machine as ASP.NET MVC 1.0 (meaning they don’t conflict and your existing ASP.NET MVC 1.0 projects will not be impacted if you install it).  If you have both ASP.NET MVC 1.0 and ASP.NET MVC 2.0 installed you’ll see two ASP.NET MVC project templates within Visual Studio 2008’s “New Project” dialog:

The release notes that come with the ASP.NET MVC 2 Preview release detail how to upgrade existing ASP.NET MVC 1.0 projects to use V2 if you’d like to migrate them forward to take advantage of the new features.

New Features

ASP.NET MVC V2 will include a bunch of new capabilities and features (some of these have already been called out on the ASP.NET MVC roadmap page).  Today’s “Preview 1” release contains a first look at some of the new features.  Many more features will show up in future preview builds.  The Preview 1 bits are still relatively early - the team is releasing today’s build to start receiving and incorporating feedback. 

Below are some quick details about some of the new Preview 1 capabilities:

Areas Support

ASP.NET MVC 2 includes support for a new feature called “areas” that allow you to more easily partition and group functionality across an MVC application.

Areas provide a means of grouping controllers and views to allow building subsections of a large application in relative isolation to other sections. Each area can be implemented as a separate ASP.NET MVC project which can then be referenced by the main application. This helps manage the complexity when building a large application and facilitates multiple teams working together on a single application together.

Below is a screen-shot that shows a single solution that has three projects.  One of the projects is named “CompanySite” and includes the core site content, layout and controllers and views. There are then two separate “Area” projects - “Blogs” and “Forums”.  These projects implement the functionality that exists under the /Blogs and /Forums URL sections of the site – and encapsulate all of the routing rules, controllers and views implementing these sections:

The Preview 1 release includes the first part of the areas feature implementation.  It doesn’t include any tool support yet (right now you need to manually add a build task to create an area project and set it up).  Future preview releases will include tooling support, and expand and refine the feature-set further.

DataAnnotation Validation Support

ASP.NET MVC 2 now includes built-in support for the DataAnnotation validation support that first shipped with .NET 3.5 SP1 – and which is used with ASP.NET Dynamic Data and .NET RIA Services.  DataAnnotations provides an easy way to declaratively add validation rules to Model and ViewModel classes within an application, and have automatic binding and UI helper validation support within ASP.NET MVC.

To see this feature in action, we can create a new “Customer” ViewModel class like below that has five properties on it (implemented using the C# automatic property feature).

We can then decorate the properties with appropriate validation rules using the DataAnnotation attributes implemented within the System.ComponentModel.DataAnnotations namespace.  The code below uses 4 different built-in validation rules – [Required], [StringLength], [Range], and [RegularExpression].  The namespace also includes a base class (ValidationAttribute) that you can subclass to create your own custom validation attributes.

We can then create a CustomersController class that has two Create action methods on it.  The first Create action method handles HTTP GET requests to the “/Customers/Create” URL, and renders a view template based on an empty Customer object.  The second Create action method handles HTTP POST requests to the same URL (and takes a Customer object as a method parameter).  It checks if there are any model binding errors to the input submitted, and if there are errors it redisplays the view template using the already entered data.  If there are no errors it displays a success view to the user:

Finally, we can right-click within either of the Create action methods above, choose the “Add View” context menu command, and automatically “scaffold” a “create” view template that is based on the Customer object.  When we do this the generated scaffolded view template will contain the below HTML <form> for our Customer:

And now when we request the “/Customers/Create” URL in our browser we’ll get an initial empty form like below:

If we enter invalid input and perform a post to the server, the ASP.NET MVC 2 model binder will detect that there are DataAnnotations attributes on our Customer class, and automatically validate the posted form input using them.  If there are errors our controller action method redisplays the form – which will cause the appropriate validation error messages to be rendered to the user like below.  Note how the validation property error message strings we specified using the DataAnnotation attributes are displayed to the user by the Html.Validation helper methods.  No extra code is required to enable this.

 

The above form will redisplay with error messages each time the user enters invalid input and attempts to perform a form post.

In a future ASP.NET MVC 2 preview we are planning to ship the jQuery Validation plugin as part of the default project template, and add support for the automatic client-side JavaScript enforcement of DataAnnotation validation rules as well.  This will enable developers to easily add validation rules in one place on either a Model or ViewModel object, and have them be enforced both client and server-side everywhere it is used within the application.

If you do not wish to annotate your model or viewmodel classes directly, you can alternatively create a “buddy class” that accompanies your model class and encapsulates the DataAnnotaton rules separately.  This capability is also useful for scenarios where VS is code-generating/updating the properties on a class directly and you cannot easily add attributes to the generated code (for example: classes generated by the LINQ to SQL or LINQ to Entities designers). 

In addition to providing built-in support for DataAnnotations, the DefaultModelBinder class in ASP.NET MVC V2 now has new virtual methods that can be overridden to easily integrate other validation frameworks as well (for example: Castle Validator, EntLib Validation, etc).  The validation UI helper methods in ASP.NET MVC are designed to support any type of validation framework (they have no direct knowledge of DataAnnotations).

Strongly Typed UI Helpers

ASP.NET MVC V2 includes new HTML UI helpers that enable you to use strong-typed lambda expressions when referencing the view template’s model object.  This enables better compile-time checking of views (so that bugs can be found at build-time as opposed to runtime), and also enables better code intellisense support within view templates.

You can see an example of the better intellisense in action below – notice how I am getting a full listing of the customer model object’s properties when using the new Html.EditorFor() helper method:

Preview 1 has built-in support for new Html.EditorFor(), Html.LabelFor(), and Html.DisplayFor() helpers.  An updated MVC futures assembly that we are shipping this week adds additional Html.TextBoxFor(), Html.TextAreaFor(), Html.DropDownListFor(), Html.HiddenFor(), and Html.ValidationMessageFor() helper methods as well (overtime these will move into the core ASP.NET MVC 2 assembly too).

Below you can see an updated version of the “create” view template for our customer creation scenario.  Notice how instead of using string expressions to reference the customer object we are instead using strongly-typed lambda expressions with the UI helpers.  We can get full intellisense and compile-time checking with all of them:

The Html.LabelFor() helper method above generates <label for="Name">Name:</label> HTML markup.

The Html.EditorFor() helper method can be used for any datatype value.  By default it is smart and will output an appropriate HTML <input/> element based on the type to be edited.  For example, it will generate <input type=”text”/> elements for the first four properties above (which are strings and integers).  It will generate a <input type=”checkbox”/> element for the final “IsActive” property – which is of type boolean.

In addition to supporting simple data-types, the Html.EditorFor() helper method also allows you to pass more complex objects with multiple properties to it.  By default it will loop over the public properties of the object and generate a <label>, <input/> element, and any appropriate validation message for each property it finds.  For example, we could re-write the above view to have just a single Html.EditorFor() call for the Customer object to conceptually output the same markup as above:

The strongly typed helpers allow you to optionally decorate the properties of the Customer ViewModel class with [DisplayName] attributes to control the label string that is output for each property used (for example: instead of having a label text of “IsActive” we could apply a [DisplayName(“Is Active Customer:”)] attribute). 

You can also add [ScaffoldColumn(false)] attributes to indicate that a particular property shouldn’t be rendered at all in scenarios like above where complex objects are passed to Html.EditorFor().

UI Helper Templating Support

The Html.EditorFor() and Html.DisplayFor() helper methods have built-in support for rendering both standard data-types as well as complex objects with multiple properties.  As noted above, they also support basic customization of rendering by applying attributes like [DisplayName] and [ScaffoldColumn] to the ViewModel.

Often developers want to be able to customize the output from UI helpers even further, though, and have total control over what is generated.  The Html.EditorFor() and Html.DisplayFor() helper methods support this via a templating mechanism that allows you to define external templates that can override and completely control the output rendered.  Better yet, you can customize the content rendered on a per-datatype/class basis.

With Preview 1 you can now optionally add an “EditorTemplates” and/or “DisplayTemplates” folder underneath either a \Views\[controllername] directory (if you want to customize the rendering for views used by a specific controller) or underneath the \Views\Shared folder (if you want to customize the rendering for all views and controllers in an application). 

You can then add partial template files to these folders to customize the output rendering performed on an individual datatype and/or class basis.  For example, below I have added an EditorTemplates folder underneath the \Views\Shared folder – and added three custom template files to it:

The “Customer.ascx” template above indicates that I want to customize the output anytime Html.EditorFor() is passed a Customer object (for example: I could customize the exact ordering/layout of the Customer properties).  The “DateTime.ascx” template above indicates that I want to customize the output anytime Html.EditorFor() is passed a DateTime property (for example: I might want to use a JavaScript datepicker instead of a plain textbox).  I could optionally add an “Object.ascx” template to the folder if I wanted to override the default rendering of all objects.

In addition to customizing rendering on a per-type basis, you can also add “named templates” to the folder.  A common scenario might be a “CountryDropDown” template that handles a string datatype – but instead of providing a standard textbox instead renders a <select> dropdownlist of country values that a user can pick from.  Below is what this editor template might look like:

We can explicitly indicate that we want to use the above template by passing its name as an argument when we invoke the Html.EditorFor() helper method.  For example, below in addition to specifying a lambda expression for our Country property, we are also specifying the name of the editor template to use when rendering it:

Alternatively, you can specify “UIHint” attributes on your ViewModel properties and types.  This allows you to indicate the default editor or display template to use in a single place, and have it be used in all views across your application (without having to explicitly pass it as an argument to Html.EditorFor). 

Below is an example of how to indicate using a UIHint attribute that the Customer.Country property (which is of type string) should by default use the CountryDropDown template when being rendered:

Once we set the above attribute on our ViewModel we no longer need to specify a template name explicitly when we use that property with Html.EditorFor().  And now when we hit refresh on our /Customers/Create URL our Country property will be rendered as a dropdown instead of a standard textbox:

Other Cool Features

ASP.NET MVC 2 Preview 1 includes a number of other small, but really nice, feature additions.  A few of my favorites include:

New [HttpPost] Attribute

It is pretty common with ASP.NET MVC to split up the handling of a URL across two action methods – one that handles GET requests and one that handles POST requests.

With ASP.NET MVC 1 you used an [AcceptVerbs(HttpVerbs.Post)] attribute to indicate the “Post” version of an action method:

This still works with ASP.NET MVC 2. Alternatively, though, you can also now take advantage of a terser [HttpPost] attribute that does the same thing:

Default Parameter Values

Handling optional parameters is a pretty common web scenario.  With ASP.NET MVC 1 you could handle optional parameters either by registering a custom routing rule and specifying a default value with it, or by marking an action method parameter as nullable and then adding code within your action method to handle whether it was null (and if so provide a default value).

ASP.NET MVC 2 Preview 1 now supports decorating action method parameters with the DefaultValueAttribute from the System.ComponentModel namespace.  This allows you to specify a parameter value that ASP.NET MVC should pass in if it is not present as part of the request.  For example, below is an example of how we could handle both the /Products/Browse/Beverages and /Products/Browse/Beverages?page=2 URLs – and have the “page” parameter value be “1” if it isn’t provided as part of the querystring:

VB today allows you to specify default parameter values directly within the VB language (avoiding the need to explicitly specify the DefaultValue attribute like above).  C# in VS2010 will also support default values with optional parameters – which will enable you to rewrite the above code simply as:

This should make handling default/optional scenarios really easy and clean.

Binding Binary Data

ASP.NET MVC Preview 1 adds support for binding base64-encoded string values to properties of type byte[] and System.Data.Linq.Binary.  There are now two overloaded versions of Html.Hidden() that can take these data-types.  These can be useful for scenarios where you want to enable concurrency control within your application and want to roundtrip timestamp values of database rows within your forms. 

Posted in: asp.net | Tags: asp.net asp.net mvc mvc mvc 2.0 v2 vs 2008 new project web application mvc web application

Put Your Views (and Pages) On a Diet

One of the complaints I often hear with our default view engine and Pages is that there’s all this extra cruft in there with the whole page directive and stuff. But it turns out that you can get rid of a lot of it. Credit goes to David Ebbo, the oracle of all hidden gems within the inner workings of ASP.NET, for pointing me in the right direction on this.

First, let me show you what the before and after of our default Index view (reformatted to fit the format for this blog).

Before
<%@ Page Language="C#" 
  MasterPageFile="~/Views/Shared/Site.Master" 
  Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" 
  ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" 
  ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" 
        title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
</asp:Content>
After
<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" 
        title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
</asp:Content>

That ain’t your pappy’s Web Form view. I can see your reaction now:

Where’s the page declaration!? Where’s all the Content IDs!? Where’s the Master Page declaration!? Oh good, at least runat="server" is still there to anchor my sanity and comfort me at night.

It turns out that ASP.NET provides ways to set many of the defaults within Web.config. What I’ve done here (and which you can do in an ASP.NET MVC project or Web Forms project) is to set several of these defaults.

In the case of ASP.NET MVC, I opened up the Web.config file hiding away in the Views directory, not to be confused with the Web.config in your application root.

default-views-web-configThis Web.config is placed here because it is the default for all Views. I then made the following changes:

  1. Set the compilation element’s defaultLanguage attribute to “C#”.
  2. Set the pages element’s masterPageFile attribute to point to ~/Views/Shared/Site.master.
  3. Set the pages element’s pageBaseType attribute to System.Web.Mvc.ViewPage (in this case, it was already set as part of the default ASP.NET MVC project template).

Below is what the web.config file looks like with my changes (I removed some details like other elements and attributes just to show the gist):

<configuration>
  <system.web>
    <compilation defaultLanguage="C#" />
    <pages
        masterPageFile="~/Views/Shared/Site.master"
        pageBaseType="System.Web.Mvc.ViewPage"
        userControlBaseType="System.Web.Mvc.ViewUserControl">
    </pages>
  </system.web>
</configuration>

With this in place, as long as my views don’t deviate from these settings, I won’t have to declare the Page directive.

Of course, if you’re using strongly typed views, you’ll need the Page directive to specify the ViewPage type, but that’s it.

Also, don’t forget that you can get rid of all them ugly Register declarations by registering custom controls in Web.config.

You can also get rid of those ugly Import directives by importing namespaces in Web.config.

<configuration>
  <system.web>
    <pages>
      <namespaces>
        <add namespace="Haack.Mvc.Helpers" />
      </namespaces>
    </pages>
  </system.web>
</configuration>

By following these techniques, you can get rid of a lot of cruft within your pages and views and keep them slimmer and fitter. Of course, what I’ve shown here is merely putting your views on a syntax diet. The more important diet for your views is to keep the amount of code minimal and restricted to presentation concerns, but that’s a post for another day as Rob has already covered it.

Sadly, there is no getting rid of runat="server" yet short of switching another view engine. But at this point, I like to think of him as that obnoxious friend from high school your wife hates but you still keep around to remind you of your roots. ;)

Hope you enjoy these tips and use them to put your views on a diet. After all, isn’t it the view’s job to look good for the beach?

Posted in: asp.net | Tags: asp.net mvc content index view reformatted format

ASP.NET MVC improvement in Visual studio 2010

ASP.NET MVC was introduced as an add-on framework to ASP.NET 3.5 SP1 in March 2009. Visual Studio 2010 will include a preview of ASP.NET MVC 2. When Visual Studio 2010 ships, it will include the RTM version of ASP.NET MVC 2. The version of ASP.NET MVC 2 that is included in ASP.NET 4 Beta 2 includes new features and capabilities.

Areas Support

Areas let you group controllers and views into sections of a large application in relative isolation from other sections. Each area can be implemented as a separate ASP.NET MVC project that can then be referenced by the main application. This helps manage complexity when you build a large application and makes it easier for multiple teams to work together on a single application.

Data-Annotation Attribute Validation Support

DataAnnotations attributes let you attach validation logic to a model by using metadata attributes. DataAnnotations attributes were introduced in ASP.NET Dynamic Data in ASP.NET 3.5 SP1. These attributes have been integrated into the default model binder and provide a metadata-driven means to validate user input.

Templated Helpers

Templated helpers let you automatically associate edit and display templates with data types. For example, you can use a template helper to specify that a date-picker UI element is automatically rendered for a System.DateTime value. This is similar to field templates in ASP.NET Dynamic Data.

The Html.EditorFor and Html.DisplayFor helper methods have built-in support for rendering standard data types as well as complex objects with multiple properties. They also support basic customization of rendering by letting you apply data-annotation attributes like DisplayName and ScaffoldColumn to the ViewModel object.

Often you want to customize the output from UI helpers even further and have total control over what is generated. The Html.EditorFor and Html.DisplayFor helper methods support this using a templating mechanism that lets you define external templates that can override and control the output rendered. The templates can be rendered on a per-class basis.

From: http://aspnetmvc.info/wp/2009/09/asp-net-mvc-improvement-in-visual-studio-2010/ Posted in: General asp.net | Tags: .net 4.0 mvc visual studio visual studio 2010 asp.net mvc framework data annotation attribute validation support html.editrofor displayname vewmodel

some Bug Fixes in asp.net mvc preview 2

The following bugs have been resolved in the ASP.NET MVC 2 Preview 2 release.

· Performance improvements were made to partial view lookup.

· Templated helpers no longer experience an infinite-recursion bug when the templates are applied to model objects with circular references.

· The default object template renders only the properties of an object and no longer attempts to render the properties of the properties of an object (that is, it no longer performs a “deep dive”). The default object template displays simple properties (primitives and value types) by converting them to a string value. For complex objects, the default object template displays a value that represents the object. If the object has a DisplayColumnAtttribute attribute applied that specifies the name of a property, the value of that property will be displayed. Otherwise , the value that results from calling the object’s ToString method is used unless it is exactly the same as the object’s full type name. In that case, the value of the first property of the object is used.

· Calling a generic templated helper with an interface type no longer throws an exception with the message “This exception should never occur”. In such cases, if there is no template for the interface, the template helpers default to an interface. The exception message was changed to be more descriptive for the case where the exception should not occur.

· Applying the RequiredAttribute attribute to a property with a type that is a value type now results in one error message instead of two.

Posted in: asp.net | Tags: asp.net mvc mvc preview 2 templated displaycolumnatttribute requiredattribute templated helpers infinite-recursion