BusinessRx Community

Dedicated to the advancement of software, technology and the people who devote their lives to it.

Welcome to BusinessRx Community Sign in | Join | Help
in Search

BusinessRx Reading List

These blog entries are written by industry experts and leaders. We consider this content to be a good read for any software developer or web technologist.

Browse by Tags

All Tags » Community News » MVC   (RSS)

  • Introducing ASP.NET MVC 3 (Preview 1)

    This morning we posted the “Preview 1” release of ASP.NET MVC 3.  You can download it here.

    We’ve used an iterative development approach from the very beginning of the ASP.NET MVC project, and deliver regular preview drops throughout the development cycle.  Our goal with early preview releases like the one today is to get feedback – both on what you like/dislike, and what you find missing/incomplete.  This feedback is super valuable – and ultimately makes the final product much, much better.

    ASP.NET MVC 3

    As you probably already surmised, ASP.NET MVC 3 is the next major release of ASP.NET MVC. 

    ASP.NET MVC 3 is compatible with ASP.NET MVC 2 – which means it will be easy to update projects you are writing with MVC 2 to MVC 3 when it finally releases.  The new features in MVC 3 build on top of the foundational work we’ve already done with the MVC 1 and MVC 2 releases – which means that the skills, knowledge, libraries, and books you’ve acquired are all directly applicable with the MVC 3 release.  MVC 3 adds new features and capabilities – it doesn’t obsolete existing ones.

    ASP.NET MVC 3 can be installed side-by-side with ASP.NET MVC 2, and you can install today’s “Preview 1” release on your machine without it impacting existing MVC 2 projects you are working on (they will continue to use MVC 2 unless you explicitly modify the projects to retarget them to MVC 3).  When you install “Preview 1” you will have a new set of ASP.NET MVC 3 project templates show up within Visual Studio 2010’s “New Project” dialog – choosing one of those when you create a new project will cause it to use MVC 3.

    Below are details about some of the new features and capabilities in today’s “Preview 1” release.  Unless otherwise noted, all of the features I describe are enabled with the preview build you can download and use today.  More ASP.NET MVC 3 features will come in future preview refreshes as we flesh out the product more and iterate on your feedback.

    View Improvements

    ASP.NET MVC 3 “Preview 1” includes a bunch of view-specific improvements.

    Add->View Dialog

    “Preview 1” includes a new “Add->View” dialog that makes it easy for you to choose the syntax you want to use when you create new view template files.  It allows you to select any of of the available view engines you have installed on your machine – giving you the ability to use whichever view templating approach feels most natural to you:

    AddView9

    There are a bunch of great open source view template engines out there (including Spark, NHaml, NDjango and more) – it is now much easier for them to integrate into Visual Studio.

    Today’s “Preview 1” build of ASP.NET MVC 3 comes with two view-engine already pre-enabled within the dialog: ASPX and Razor. 

    New “Razor” View Engine

    Earlier this month I blogged about the new “Razor” view engine we’ve been working on.  Based on the comments in the post, a lot of people are eagerly waiting to use it.  The good news is that you can start using it with today’s “Preview 1” release.

    Simple Razor Example

    Let’s build a super-simple store site that lists product categories, and allows visitors to click the categories to see a listing of products within them.  You can download a completed version of this sample here.

    image

    Below is a StoreController class that implements the two action methods (“Index” and “Browse”) needed to build the above scenario:

    image

    We’ll use the new “Razor” view engine to implement the view templates for our StoreController.

    Below is the “Layout.cshtml” layout-page that will define the common layout UI we want across our site.  The “RenderBody()” method indicates where view templates that are based on this master layout file should “fill in” the body content:

    image

    Below is the view template for the Index action.  It is based on the above layout page, and outputs a <ul> list of category names: 

    image

    The template above is using the standard Html.ActionLink() helper method in ASP.NET MVC to render a hyperlink that links to the “Browse” action method of our StoreController.  All of existing HTML helper methods in ASP.NET MVC work in “Razor” views – this is true both for the HTML helper methods built-into ASP.NET MVC, as well as those built by others (including vendors and the MvcContrib project).

    Below is the view template for the Browse action.  It lists the products within a specific category:

    image

    Notice above how we are using the “Model” property within our foreach statement to access the strongly-typed List of products we passed from our Controller.  We are doing this just like we would within .aspx view templates.  Razor also supports a “View” property which allows us to access un-typed “ViewData” passed to the view template.  “View” is a dynamic property (a new feature of .NET 4) – which gives us a slightly cleaner syntax when accessing ViewData.  Instead of writing ViewData[“Cateogry”] we can now just write View.Category.

    Clean and Concise

    The code in the screen-shots above contains everything we need to write to implement our Controller + Views.  “Razor” helps make view templates clean and concise, and I think you’ll find it enables a very fluid coding workflow. Read my “Razor” blog post from earlier in the month to learn more about the syntax and understand how it works.  You can download a running version of the above sample here.

    Code Intellisense and Colorization

    One of the things you might have noticed from the screen-shots above is that “Razor” file colorization and code intellisense is not yet supported in Visual Studio with today’s “Preview 1” release.  We will be enabling full code intellisense and colorization with a future preview refresh.  The VS 2010 editor will support Razor file intellisense for C#/VB code, as well as for HTML/CSS/JavaScript. 

    Other Improvements in the Future

    Three other enhancements we are working to enable in a future preview refresh are:

    • The ability to use a @model statement at the top of a “Razor” file instead of having to explicitly inherit from a base class.  This reduces the code and simplifies it.  
    • The ability to specify a default LayoutPage for the site to avoid having to explicitly set it within each view template.  This further reduces the code within the view template, and makes your code more DRY.
    • The ability to unit-test individual “Razor” template files without having to run the application or launch a web-server.

    With these first two changes the above Browse template will be able to be written as simply:

    image

    The above template syntax will be supported in a future preview refresh.  Full colorization and code-intellisense will be provided within the editor.

    Controller Improvements

    ASP.NET MVC 3 “Preview 1” includes several nice controller-specific enhancements.

    Global Filters

    ASP.NET MVC supports the ability to declaratively apply “cross-cutting” logic using a mechanism called “filters”.  You can specify filters on Controllers and Action Methods today using an attribute syntax like so:

    image

    Developers often want to apply some filter logic across all controllers within an application.  ASP.NET MVC 3 now enables you to specify that a filter should apply globally to all Controllers within an application.  You can now do this by adding it to the GlobalFilters collection.  A RegisterGlobalFilters() method is now included in the default Global.asax class template to provide a convenient place to do this (it is then called by the Application_Start() method):

    image

    The filter resolution logic in MVC 3 is flexible so that you can configure a global filter that only applies conditionally if certain conditions are met (for example: debugging is enabled, or if a request uses a particular http verb, etc).  Filters can also now be resolved from a Dependency Injection (DI) container – more on that below.

    New Dynamic ViewModel Property

    ASP.NET MVC Controllers have supported a “ViewData” property that enables you to pass data to a view template using a late-bound dictionary API.  For example:

    image

    The “ViewData” API is still supported in ASP.NET MVC 3.  MVC 3 augments it, though, with a new “ViewModel” property on Controller that is of type “dynamic” – and which enables you to use the new dynamic language support within VB and C# to pass ViewData items using a slightly cleaner syntax than the current dictionary API.  Now you can alternatively write the following code to achieve the same result as above:

    image

    You do not need to define any strongly-typed classes to use the ViewModel property.  Because it is a “dynamic” property you can instead just get/set properties on it and it will resolve them dynamically at runtime.  It internally stores the property name/value pairs within the ViewData dictionary.

    New ActionResult Types

    ASP.NET MVC 3 “Preview 1” includes several new ActionResult types and corresponding helper methods.

    HttpNotFoundResult

    The new HttpNotFoundResult class is used to indicate that a resource requested by the current URL was not found. It returns a 404 HTTP status code to the calling client. You can optionally use the new HttpNotFound() helper method on Controller to return an instance of this action result type, as shown in the following example:

    image

    Permanent Redirects

    The HttpRedirectResult class has a new Boolean “Permanent” property that is used to indicate whether a permanent redirect should occur. A permanent redirect uses the HTTP 301 status code.  In conjunction with this change, the Controller class now has three new methods for performing permanent redirects: RedirectPermanent(), RedirectToRoutePermanent(), and RedirectToActionPermanent().  These methods return an instance of HttpRedirectResult with the Permanent property set to true.

    HttpStatusCodeResult

    The new HttpStatusCodeResult class can be used to set an explicit response status code and description. 

    JavaScript and AJAX Improvements

    ASP.NET MVC 3 includes built-in JSON binding support that enables action methods to receive JSON-encoded data and model-bind it to action method parameters. 

    To see this feature in action, consider the jQuery client-side JavaScript below.  It defines a “save” event handler that will be invoked when a save button is clicked on the client.  The code within the event handler constructs a client-side JavaScript “product” object with three fields whose values are retrieved from HTML input elements.  It then uses jQuery’s .ajax() method to POST a JSON based request containing the product to a /Store/UpdateProduct URL on the server:

    image

    ASP.NET MVC 3 now enables you to implement the /Store/UpdateProduct URL on the server using an action method like below:

    image

    The UpdateProduct() action method above accepts a strongly-typed Product object as a parameter.  ASP.NET MVC 3 can now automatically bind the incoming JSON post values to the .NET Product type on the server – without you having to write any custom binding or marshalling logic.  ASP.NET MVC’s built-in model and input validation features all work as you’d expect with this.

    We think this capability will be particularly useful going forward with scenarios involving client templates and data binding (like I’ve previously blogged about here).  Client templates will enable you to format and display a single data item or set of data items by using templates that execute on the client.  ASP.NET MVC 3 will enable you to easily connect client templates with action methods on the server that return and receive JSON data.

    Other JavaScript/AJAX Improvements in the Future

    Future preview refreshes of ASP.NET MVC 3 will include better support for unobtrusive JavaScript.  ASP.NET MVC 3 will also directly support the jQuery Validation library from within its built-in validation helper methods.

    Model Validation Improvements

    ASP.NET MVC 2 came with significant model validation improvements.  You can read my previous blog post to learn more about them.

    ASP.NET MVC 3 extends this work further, and adds support for several of the new validation features introduced within the System.ComponentModel.DataAnnotations namespace in .NET 4. In particular:

    • MVC 3 supports the new .NET 4 DataAnnotations metadata attributes such as DisplayAttribute.
    • MVC 3 supports the improvements made to the ValidationAttribute class in .NET 4.  The ValidationAttribute class was improved in .NET 4 to support a new IsValid overload that provides more information about the current validation context, such as what object is being validated.  This enables richer scenarios where you can validate the current value based on another property of the model. 
    • MVC 3 supports the new IValidatableObject interface introduced in .NET 4.  The IValidatableObject interface enables you to perform model-level validation, and enables you to provide validation error messages specific to the state of the overall model, or between two properties within the model. 

    Below is an example of using the IValidatableObject interface built-into .NET 4 to implement a custom validation method on a class.  This method can apply validation rules across multiple properties and yield back multiple validation errors (and optionally include both an error message like below as well as a list of property names that caused the violation):

    image

    ASP.NET MVC 3 now honors the IValidateObject interface when model binding (in addition to all of the other validation approaches it already supported with MVC 2), and will retrieve validation errors from it and automatically flag/highlight impacted fields within a view using the built-in HTML form helpers:

    image

    ASP.NET MVC 3 also introduces a new IClientValidatable interface that allows ASP.NET MVC to discover at runtime whether a validator has support for client validation.  This interface has been designed so that it can be integrated with a variety of validation frameworks.  MVC 3 also introduces a new IMetadataAware interface that simplifies how you can contribute to the ModelMetadata creation process. 

    Dependency Injection Improvements

    ASP.NET MVC 3 provides better support for applying Dependency Injection (DI) and integrating with Dependency Injection/IOC containers.

    In “Preview 1”, we’ve added support for dependency injection in the following places:

    • Controllers (registering & injecting controller factories, injecting controllers)
    • Views (registering & injecting view engines, injecting dependencies into view pages)
    • Action Filters (locating & injecting filters)

    For future previews we are investigating adding dependency injection support for:

    • Model Binders (registering & injecting)
    • Value Providers (registering & injecting)
    • Validation Providers (registering & injecting)
    • Model metadata Providers (registering & injecting)

    ASP.NET MVC 3 will support the Common Service Locator library, and any DI container that supports it’s IServiceLocator interface.  This will make it really easy to integrate any DI container that supports the Common Service Locator with ASP.NET MVC.

    Note: In Preview 1, we redefined the CSL interface in our codebase, and didn’t include the CSL DLL in our setup. This means that existing implementations of CSL won’t “just work” with “preview 1” – instead they’ll have to recompile their CSL implementations against our interface to make them work. Future preview refreshes will make this CSL library dependency easier, and avoid this extra step.

    Brad Wilson is starting a great blog series on ASP.NET MVC 3’s Dependency Injection Support.  Below are links to his first few articles about it:

    Click here to download a simple ASP.NET MVC 3 example that demonstrates how to use the popular Ninject Dependency Injection Container with ASP.NET MVC 3. 

    Downloads and Links

    Click here to download ASP.NET MVC 3 Preview 1.  Post feedback/issues about it in the ASP.NET MVC Forum.

    Once ASP.NET MVC 3 is installed, you can download and run the simple Razor sample I demonstrated in the blog post above. 

    Read my previous “Razor” blog post to learn more about how it works and its syntax.  Also read my recent EF4 Code-First and EF4 Code-First Schema Mapping posts to learn more about the database code and clean model layer I built using EF4 Code-First and SQL Express within the above sample.

    Summary

    We are excited to get today’s ASP.NET MVC 3 “Preview 1” release in people’s hands, and start receiving feedback on it. 

    Our primary goal with these early preview releases is to get feedback – both on what you like/dislike, and what you find missing/incomplete.  This feedback is super valuable – and ultimately makes the final product much, much better.  If you do install today’s “Preview 1” build, please post your feedback and any bugs/issues you find to the ASP.NET MVC forum at http://forums.asp.net.  The team will be monitoring this forum closely, and will be happy to help with anything you run into. 

    We will then iterate on the feedback you send us, and further refine ASP.NET MVC 3 in future preview refreshes.

    Hope this helps,

    Scott

    P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

  • Code-First Development with Entity Framework 4

    .NET 4 ships with a much improved version of Entity Framework (EF) – a data access library that lives in the System.Data.Entity namespace.

    When Entity Framework was first introduced with .NET 3.5 SP1, developers provided a lot of feedback on things they thought were incomplete with that first release.  The SQL team did a good job of listening to this feedback, and really focused the EF that ships with .NET 4 on addressing it. 

    Some of the big improvements in EF4 include:

    • POCO Support: You can now define entities without requiring base classes or data persistence attributes.
    • Lazy Loading Support: You can now load sub-objects of a model on demand instead of loading them up front.
    • N-Tier Support and Self-Tracking Entities: Handle scenarios where entities flow across tiers or stateless web calls.
    • Better SQL Generation and SPROC support: EF4 executes better SQL, and includes better integration with SPROCs
    • Automatic Pluralization Support: EF4 includes automatic pluralization support of tables (e.g. Categories->Category).
    • Improved Testability: EF4’s object context can now be more easily faked using interfaces.
    • Improved LINQ Operator Support: EF4 now offers full support for LINQ operators.

    Visual Studio 2010 also includes much richer EF designer and tooling support. The EF designer in VS 2010 supports both a “database first” development style – where you construct your model layer on a design surface from an existing database.  It also supports a “model first” development style – where you first define your model layer using the design surface, and can then use it to generate database schema from it.

    Code-First Development with EF

    In addition to supporting a designer-based development workflow, EF4 also enables a more code-centric option which we call “code first development”.  Code-First Development enables a pretty sweet development workflow.  It enables you to:

    • Develop without ever having to open a designer or define an XML mapping file
    • Define your model objects by simply writing “plain old classes” with no base classes required
    • Use a “convention over configuration” approach that enables database persistence without explicitly configuring anything
    • Optionally override the convention-based persistence and use a fluent code API to fully customize the persistence mapping

    EF’s “code first development” support is currently enabled with a separate download that runs on top of the core EF built-into .NET 4.  CTP4 of this “code-first” library shipped this week and can be downloaded here

    It works with VS 2010, and you can use it with any .NET 4 project (including both ASP.NET Web Forms and ASP.NET MVC).

    Step by Step Tutorial: Building NerdDinner using a Code-First Approach

    Last year I wrote an ASP.NET MVC 1.0 tutorial that was published both online and in a book.  The tutorial walked through creating a simple application, called “NerdDinner”, which provides an easy way for people to organize, host and RSVP for dinners online.  You can read my original ASP.NET V1 NerdDinner tutorial here.  An updated version of the tutorial is also included in the new Professional ASP.NET MVC 2 book.

    The NerdDinner tutorial used a “database first approach” where the database schema was defined first, and then we used a Visual Studio designer to create our LINQ to SQL / LINQ to Entities model objects that mapped to it.  

    Below I’m going to demonstrate how we could instead use a “code first approach” using EF4 to build the NerdDinner model layer and database schema, and construct a CRUD application using ASP.NET MVC.

    image

    We will walkthrough building this application step-by-step.  A download link to a completed version of the sample is available at the end of this blog post.

    Step 1: Create a New Empty ASP.NET MVC 2 Application

    We’ll start by creating a new ASP.NET MVC 2 Project within Visual Studio 2010.  Choose File->New Project and use the “ASP.NET MVC 2 Empty Web Application” project template to do this.

    This will create an empty ASP.NET MVC 2 project that does not have any controllers, models or views within it:

    image

    We’ll next work to define our NerdDinner “model” – which refers to the objects that represent the data of our application, as well as the corresponding domain logic that integrates validation and business rules with it.  The model is the "heart" of an MVC-based application, and fundamentally drives the behavior of it.  We’ll create this model layer using the new EF4 “Code First” capabilities.

    Step 2: Create our Model

    Let’s assume we do not already have a database defined, and that we are building our new NerdDinner application completely from scratch.

    We do not need to start with a database

    When using a code-first development workflow, we do not need to begin our application by creating a database or specifying schema.  Instead we can begin by writing standard .NET classes that define the domain model objects that are most appropriate for our application – without having to worry about intermixing data persistence logic within them.

    Creating Model Classes

    NerdDinner is a small application, and our data storage needs with it are pretty simple.  We want to be able to define and store “Dinners” that refer to specific events that people can attend.  We also want to be able to define and store “RSVP” acceptances, which are used to track a person’s interest in attending a particular Dinner.

    Let’s create two classes (Dinner and RSVP) to represent these concepts.  We’ll do this by adding two new classes to our ASP.NET MVC project - “Dinner” and “RSVP”:

    image

    The above “Dinner” and “RSVP” model classes are “plain old CLR objects” (aka POCO).  They do not need to derive from any base classes or implement any interfaces, and the properties they expose are standard .NET data-types.  No data persistence attributes or data code has been added to them. 

    The ability to define model classes without having to tie them to a particular database, database API, or database schema implementation is really powerful – and provides us with much more data access flexibility.  It allows us to focus on our application/business needs without having to worry about persistence implementation.  It also gives us the flexibility to change our database schema or storage implementation in the future – without having to re-write our model objects, or the code that interacts with them.

    Creating a Context Class to Handle Database Persistence

    Now that we’ve defined our two POCO model classes, let’s create a class that we can use to handle the retrieval/persistence of Dinner and RSVP instances from a database. 

    We’ll name this class “NerdDinners”. It derives from the DbContext base class, and publishes two public properties – one that exposes our Dinner objects, and one that exposes our RSVP objects:

    image

    The DbContext and DbSet classes used above are provided as part of the EF4 Code-First library.  You’ll need to add a reference to the System.Data.Entity.CTP assembly that is installed into the \Program Files\Microsoft ADO.NET Entity Framework Feature CTP4\Binaries directory to reference these classes.  You’ll also want to add a “using System.Data.Entity” namespace statement at the top of your “NerdDinners” class file.

    That is all the code we need to write

    The above three classes contain all of the code necessary to implement a basic model and data persistence layer for our NerdDinner application.  We do not need to configure any additional database schema mapping information, nor run any tools, nor edit any XML files, nor use any designers in order to start using our classes to retrieve, update, and save data into a database.

    Convention Based Persistence Mapping

    We do not need to write any additional code, nor create any XML files, nor use any tools in order to map our model classes to and from a database.  How, you might ask, is that possible?

    By default, EF code-first supports a “convention over configuration” approach that enables you to rely on common mapping conventions instead of having to explicitly configure things.  You can override these conventions if you want to provide custom database mapping rules.  But if you instead just use the default conventions you’ll find that the amount of code you have to write is really small, and the common 90% of scenarios “just work” the way you’d expect them to without any extra code or configuration.

    In our example above, our NerdDinners context class will by default map its “Dinners” and “RSVPs” properties to “Dinners” and “RSVPs” tables within a database.  Each row within the Dinners table will map to an instance of our “Dinner” class.  Likewise, each row within the RSVPs table will map to an instance of our “RSVP” class.  Properties within the “Dinner” and “RSVP” classes in turn map to columns within the respective “Dinners” and “RSVPs” database tables.

    Other default conventions supported by EF include the ability to automatically identify primary-key and foreign keys based on common naming patterns (for example: an ID or DinnerID property on the Dinner class will be inferred as the primary key).  EF also includes smart conventions for wiring-up association relationships between models.  The EF team has a blog post that talks more about how the default set of conventions work here.

    Code Examples of How to Use Our Model

    The three classes we created earlier contain all of the code necessary to implement our model and data persistence for NerdDinner.  Let’s now look at a few code examples of how we can use these classes to perform common data scenarios:

    Query Using LINQ Expressions

    We can write LINQ query expressions to retrieve data from a database using the following code.  Below we are using a LINQ expression to retrieve all dinners that occur in the future:

    image

    We can also take advantage of relationships between Dinners and RSVPs when writing our LINQ expressions.  Notice below how our “where” statement filters by dinners whose RSVP count is greater than 0:

    image

    Note that the “where” filter in the above query (where we are retrieving only those Dinners who have at least one RSVP) executes in the database server – making the query and the amount of data we retrieve very efficient.

    Retrieving a Single Instance

    We can use LINQ’s Single() method with a lambda query to retrieve a single instance of a Dinner using code like below:

    image

    Alternatively, we can also take advantage of a Find() method that EF “code-first” exposes that allows you to easily retrieve an instance based on its ID:

    image

    Adding a new Dinner

    The code below demonstrates how to create and add a new Dinner to the database.  All we need to do is to “new” a Dinner object, set properties on it, and then add it to the Dinners property of our NerdDinners context object.  The NerdDinner context class supports a “unit of work” pattern that enables you to add multiple models to the context, and then call “SaveChanges()” on it to persist all of the changes to a database as a single atomic transaction.

    image

    Updating a Dinner

    The code below demonstrates how to retrieve a Dinner, update one of its properties, and then save the changes back to the database:

    image

    Step 3: Create a ASP.NET MVC Controller that uses our Model

    Let’s now look at a more complete scenario involving our model, where we use a controller class to implement the functionality necessary to publish a list of upcoming dinners, and enable users to add new ones:

    image

    We’ll implement this functionality by right-clicking on the “Controllers” folder and choose the “Add->Controller” menu command.  We’ll name our new controller “HomeController”.

    We’ll then add three “action methods” within it that work with the NerdDinners model we created earlier using EF “Code-First”:

    image

    The “Index” action method above retrieves and renders a list of upcoming dinners. 

    The “Create” action methods allow users to add new dinners.  The first “Create” method above handles the “HTTP GET” scenario when a user visits the /Home/Create URL, and send back a “New Dinner” form to fill out.  The second “Create” method handles the “HTTP POST” scenario associated with the form – and handles saving the dinner in the database.  If there are any validation issues it redisplays the form back to the user with appropriate error messages.

    Adding Views for our Controllers

    Our next step will be to add two “View templates” to our project – one for “Index” and one for “Create”. 

    We’ll add the “Index” view to our project by moving our cursor within the Index action method of our controller, and then right-click and choose the “Add View” menu command.  This will bring up the “Add View” dialog.  We’ll specify that we want to create a strongly-typed view, and that we are passing in a IEnumerable list of “Dinner” model objects to it:

    image

    When we click “Add”, Visual Studio will create a /Views/Home/Index.aspx file.  Let’s then add the following code to it – which generates a <ul> list of Dinners, and renders a hyperlink that links to our create action:

    image

    We’ll then add the “Create” view to our project by moving our cursor within the Create action method of our controller, and then right-click and choose the “Add View” menu command.  Within the “Add View” dialog we’ll specify that we want to create a strongly-typed view, and that we are passing it a Dinner object.  We’ll also indicate that we want to “scaffold” using a “Create” template:

    image

    When we click “Add”, Visual Studio will create a /Views/Home/Create.aspx file with some scaffold-generated content within it that outputs an HTML <form> for a “Dinner” object.  We’ll tweak it slightly and remove the input element for the DinnerID property.  Our final view template content will look like this:

    image

    We have now implemented all of the code we need to write within our Controller and Views to implement the Dinner listing and Dinner creation functionality within our web application.

    Step 4: The Database

    We’ve written our code.  Now let’s run the application. 

    But what about the database?

    We don’t have a database yet – and haven’t needed one so far because our “code first” development workflow hasn’t required us to have one to define and use our model classes. 

    But we will need a database when we actually run our application and want to store our Dinner and RSVP objects.  We can create the database one of two ways:

    1. Manually create and define the schema ourselves using a database tool (e.g. SQL Management Studio or Visual Studio)
    2. Automatically create and generate the schema directly from our model classes using the EF Code-First library

    This second option is pretty cool and is what we are going to use for our NerdDinner application.

    Configuring our Database Connection String

    To begin with, we’ll setup a connection-string to point to where we want our database to live.  We’ll do this by adding a “NerdDinners” connection-string entry to our application’s web.config file like so: 

    image 

    By default, when you create a DbContext class with EF code-first, it will look for a connection-string that matches the name of the context-class.  Since we named our context class “NerdDinners”, it will by default look for and use the above “NerdDinners” database connection-string when it is instantiated within our ASP.NET application.

    Taking advantage of SQL CE 4

    You can use many different databases with EF code-first – including SQL Server, SQL Express and MySQL.

    Two weeks ago I blogged about the work we are also doing to enable the embedded SQL CE 4 database engine to work within ASP.NET.  SQL CE 4 is a lightweight file-based database that is free, simple to setup, and can be embedded within your ASP.NET applications.  It supports low-cost hosting environments, and enables databases to be easily migrated to SQL Server.

    SQL CE can be a useful option to use when you are in the early stages of defining (and redefining) your model layer – and want to be able to quickly create and recreate your database as you do so.  We’ll use SQL CE 4 to begin with as we develop our NerdDinner application.  We can later optionally change the connection-string to use SQL Express or SQL Server for production deployment – without having to modify a single line of code within our application.

    The connection-string I specified above points to a NerdDinners.sdf database file, and specifies the SQL CE 4 database provider.  In order for this to work you need to install SQL CE 4 – either via the Standalone SQL CE Installer or by installing WebMatrix (which includes it built-in).  SQL CE 4 is a small download that only takes a few seconds to install.

    Important: In the connection-string above I’m indicating that we want to create the NerdDinners.sdf file within the |DataDirectory| folder – which in an ASP.NET application is the \App_Data\ folder immediately underneath the application directory.  By default the “Empty ASP.NET MVC Web Application” project template does not create this directory.  You will need to explicitly create this directory within your project (right click on the project and choose the “Add->ASP.NET Folder->Add_Data” menu item).

    Automatic Database Schema Creation

    EF code-first supports the ability to automatically generate database schema and create databases from model classes – enabling you to avoid having to manually perform these steps.

    This happens by default if your connection-string points to either a SQL CE or SQL Express database file that does not already exist on disk.  You do not need to take any manual steps for this to happen.

    To see this in action, we can press F5 to run our NerdDinner application.  This will launch a browser at the root “/” URL of our application.  You should see a screen like below rendered back:

    image

    The “/” URL to our application invoked the HomeController.Index() action method – which instantiated and queried our NerdDinners context object to retrieve all upcoming Dinners from our database.  Because the NerdDinners.sdf database file we pointed our connection-string to didn’t already exist, the EF code-first library automatically generated it for us.  It used our NerdDinners context object to automatically infer the database schema for the database it generated. 

    To see the SQL CE database file that was generated, click the “Show all Files” icon within the Visual Studio solution explorer, and then press the “Refresh” button and expand the App_Data folder:

    image 

    We will be shipping an update to VS 2010 in the future that enables you to open up and edit SQL CE 4 databases within the “Server Explorer” tab (just like you do with SQL databases today).  This will enable you to easily see (and optionally tweak) the schema and contents of the database.  Until then you can optionally use the database tools within WebMatrix to examine the SQL CE 4 database file’s contents. 

    We did not specify any custom persistence mapping rules with our NerdDinners context – so the database that was generated followed the default EF code-first naming conventions to map the schema.  If we had specified any custom mapping rules, though, the EF code-first library would have honored those and generated a database that matched them. 

    Just to refresh our memory – here are the two POCO model classes and the NerdDinners context class that we defined earlier:

    image

    Below are the tables that were added when we ran our application and the database was automatically created based on the above model:

    image 

    The definition of the “Dinners” table looks like below.  The column names and data-types map to the properties of the Dinner class we defined.  The DinnerID column has also been configured to be both a primary key and an identity column:

    image

    The definition of the “RSVPs” table looks like below.  The column names and data-types map to the properties of the RSVP class we defined.  The RsvpID column has also been configured to be both a primary key and an identity column:

    image

    A one to many primary key/foreign key relationship was also established between the Dinners and RSVPs tables.  The EF code-first library inferred that this should be established because our Dinner class has an ICollection<RSVP> property named RSVPs, and the RSVP class has a Dinner property.  

    Populating the Database with some Dinners

    Let’s now create and add some Dinners to our database.  We’ll do this by clicking the “Create New Dinner” link on our home-page to navigate to our “Create” form:

    image

    When we click the “Create” button, our new Dinner will be saved in the database.  We can repeat this multiple times to register several different Dinners.  Each new Dinner we create will be persisted within our database and show up in our Home listing of upcoming dinners:

    image 

    Step 5: Changing our Model

    We are going to continually evolve and refactor our model as our application grows.  The EF code-only library includes some nice development features that make it easier to coordinate this evolution with a development database.

    Adding a new Property to the Dinner Model

    Let’s walkthrough making a simple change to our Dinner class.  Specifically, we’ll add an additional property to our Dinner class called “Country”:

    image

    Now that we’ve made this change, let’s press F5 in Visual Studio to build and re-run the application.  When we do this we’ll see the below error message:

    image

    This error message occurs because we’ve changed the structure of our Dinner class, and our model object is now no longer the same shape as the “Dinners” table we automatically created within our database. 

    When EF automatically creates a database for you, it by default adds an “EdmMetadata” table to the database that tracks the shape of the model objects that were used to automatically create the database schema for you: 

    image

    The error message above occurs when EF detects that you’ve made a change to a model object and it is now out of sync with the database it automatically created for you. 

    Re-synchronizing our Model Classes with the Database

    There are a couple of ways we can “re-sync” our model objects and our database:

    • We can manually update our database schema to match our models
    • We can manually delete our database file, re-run the application, and have EF automatically re-create the database
    • We can enable a feature of EF code-first that automatically updates our database for us whenever we change our models

    Let’s look at how we can use this last automatic option with our NerdDinner application.

    The RecreateDatabaseIfModelChanges Feature

    CTP 4 of the EF Code First library includes a useful development-time feature that enables you to automatically re-create your database anytime you make modifications to your model classes.  When you enable it, EF identifies when any of the model classes that were used to automatically create a database are modified, and when that happens can re-create your database to match the new model class shape – without you having to take any manual steps to do so.

    This capability is especially useful when you are first developing an application, since it gives you the freedom and flexibility to quickly refactor and restructure your model code however you want - without having to do any manual work to keep your database schema in sync along the way.  It works especially well with SQL CE – since it is a file-based database that can be dropped and recreated on the fly in under a second.  This can enable an incredibly fluid development workflow.

    The easiest way to enable this capability is to add a Database.SetInitializer() call to the Application_Start() event handler within our Global.asax class:

    image

    This tells EF to re-create our NerdDinners.sdf database to match our NerdDinners model anytime our model classes change shape.  Now when we re-run our application we will no longer get that error message telling us that our model classes and database are out of sync.  EF will instead automatically re-create a database for us that matches our new model class shape, and our application will run fine:

    image

    Seeding Initial Data in Automatically Created Databases

    One of the things you might have noticed in the above screen-shot is that we lost our dinner data when we recreated the database.  This is because the automatic “RecreateDatabaseIfModelChanges” behavior isn’t intended for production scenarios where you want to “migrate” existing data from one schema to another.  Instead it is designed for development scenarios where you want the database to be quickly and automatically updated for you – without you having to take any manual steps or specify migration rules to do so. 

    Note: We are separately working to provide better data migration support for scenarios where you are working with production data and want to version the schema.  We think of that as a different scenario than this early development-time feature that I’m describing here.  The data migration capability isn’t enabled yet with this week’s CTP.

    EF supports the ability for us to optionally “seed” our generated database with default/test data anytime the database is created/recreated.  I find this feature really useful since it enables me to refactor a model, and then quickly run the application to try out a scenario – without having to enter in a bunch of test data manually to do so.

    We can “seed” our NerdDinners database with default data by writing a “NerdDinnersIntializer” class like below.  I’m using it to create two “sample dinners” and adding them to our database like so:

    image

    We can then update the Database.Initializer() call we added to our Global.asax to use this “NerdDinnersInitializer” class at startup:

    image

    And now anytime we make a change to one of our NerdDinner model classes, the database will be automatically dropped and recreated to match our models, and we’ll have two dinners already seeded in the database for testing purposes:

    image

    Easy Refactoring

    The above features make it really easy to evolve and refactor your code at development time – without having to use tools or run scripts to manually keep your database in sync with your code changes.

    Because our model classes, LINQ expressions, and “seed” test data are all strongly typed, we can also take advantage of refactoring tool support inside Visual Studio to quickly and automatically apply changes across our code base in a quick and easy way.

    Step 6: Adding Validation Rules

    We’ve built a nice, simple data-entry application.

    One problem with it, though, is that we don’t currently have any type of input validation in place to ensure that fields are filled out correctly within our Create Dinner form.  Let’s fix that.

    Adding Validation using DataAnnotations

    Validation rules in an ASP.NET MVC based application are usually best expressed within a model.  This enables them to be maintained in a single place, and enforced across any number of controllers and views that might interact with them.  ASP.NET MVC enables you to implement validation rules using a variety of different mechanisms, and is flexible enough to support just about any validation scheme you want to use. 

    ASP.NET MVC 2 includes built-in support for using .NET’s System.ComponentModel.DataAnnotations library of validation rules – which enable you to declaratively apply validation rules to model classes using validation attributes.  You can learn more about this capability in a previous blog post I wrote.  We’ll take advantage of this approach to enable input validation for our NerdDinner application.

    Let’s go back to the Dinner class we defined earlier and add some validation attributes to its properties (note: we need to add a “using System.ComponentModel.DataAnnotations” namespace as well):

    image

    The [Required] validation attribute indicates that a particular property must be specified.  The [StringLength] validation attribute allows us to indicate a maximum length for a particular string property.  The [RegularExpression] validation attribute allows us to indicate that a particular string property must match a specified regular expression in order to be valid – in this case an email address.

    Each of the validation attributes supports an “ErrorMessage” property – which allows us to specify an error message that should be displayed if the validation fails.  This can either be hard-coded as a string (like above) or pulled from a resource – enabling it to be easily localized.

    Referencing some CSS and JavaScript files

    The last step will be to go back to our Create.aspx view template and add a <link> reference to a Site.css file in our project, as well as two <script> elements that reference two JavaScript files in our project.  We’ll also add one line of code to call Html.EnableClientValidation() before our <form> element is rendered:

    image

    These changes will ensure that any validation error messages that are displayed in the page are styled (to make them more visible), and that the validation rules we apply on our model will be applied both on the client and on the server.

    Running the Application

    Let’s re-run the application and try to create a new Dinner.  Let’s begin by pushing the “Create” button with no values filled out.  We’ll find that we now see the validation error messages we applied to our model showing up in the browser:

    image

    Because we enabled client-side validation with ASP.NET MVC (that was the one line of code we wrote above), our error messages will update and change in real-time:

    image

    Notice above how our validation error message changed once our “Title” became longer than 20 characters.  This is because we have a [StringLength] property on our Dinner.Title property that indicates a maximum allowed size of 20 characters.  As we started entering a value within the “HostedBy” textbox, our error message likewise changed from the “[Requred]” error message (which asks you to enter your email address) to the “[RegularExpression]” error message (which is telling us we don’t have a valid email address).

    These validation rules work both within the browser (via JavaScript) and on the server (enabling us to protect ourselves even if someone tries to bypass the JavaScript validation) – without us having to make any changes to our controller class.  The ability to specify these rules once within our model, and have them apply everywhere, is extremely powerful – and will enable us to continue to evolve our application in a very clean way. 

    You can learn more about these ASP.NET MVC 2 Model Validation features and how they work here.

    Download

    Click here to download and run the above NerdDinnerReloaded sample we’ve built in this blog post.  It requires VS 2010 (or the free Visual Web Developer 2010 Express). 

    Important: You must download and install SQL CE 4 on your machine for the above sample to work.  You can download the EF Code-First library here.  Neither of these downloads will impact your machine.

    Summary

    This week’s CTP4 release of the “EF Code-First” functionality provides a pretty nice code-centric way to work with data.  It brings with it a lot of productivity, as well as a lot of power.  In today’s tutorial I focused mostly on some of the new productivity enhancements provided with the CTP4 release.  There are many more scenarios we could drill into including its Fluent API for enabling custom persistence mapping rules, its improved testability support, and other more advanced capabilities.

    You can download this week’s CTP4 release of EF Code-First here.  To learn even more about “EF Code-First” check out these blog posts by the ADO.NET team:

    Hope this helps,

    Scott

    P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

  • Introducing “Razor”

    One of the things my team has been working on has been a new view engine option for ASP.NET.

    ASP.NET MVC has always supported the concept of “view engines” – which are the pluggable modules that implement different template syntax options.  The “default” view engine for ASP.NET MVC today uses the same .aspx/.ascx/.master file templates as ASP.NET Web Forms.  Other popular ASP.NET MVC view engines used today include Spark and NHaml.

    The new view-engine option we’ve been working on is optimized around HTML generation using a code-focused templating approach. The codename for this new view engine is “Razor”, and we’ll be shipping the first public beta of it shortly.

    Design Goals

    We had several design goals in mind as we prototyped and evaluated “Razor”:

    • Compact, Expressive, and Fluid: Razor minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding workflow. Unlike most template syntaxes, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type.

    • Easy to Learn: Razor is easy to learn and enables you to quickly be productive with a minimum of concepts. You use all your existing language and HTML skills.

    • Is not a new language: We consciously chose not to create a new imperative language with Razor. Instead we wanted to enable developers to use their existing C#/VB (or other) language skills with Razor, and deliver a template markup syntax that enables an awesome HTML construction workflow with your language of choice.

    • Works with any Text Editor: Razor doesn’t require a specific tool and enables you to be productive in any plain old text editor (notepad works great).

    • Has great Intellisense: While Razor has been designed to not require a specific tool or code editor, it will have awesome statement completion support within Visual Studio. We’ll be updating Visual Studio 2010 and Visual Web Developer 2010 to have full editor intellisense for it.

    • Unit Testable: The new view engine implementation will support the ability to unit test views (without requiring a controller or web-server, and can be hosted in any unit test project – no special app-domain required).

    We’ve spent the last few months building applications with it and doing lots of usability studies of it with a variety of volunteers (including several groups of non-.NET web developers). The feedback so far from people using it has been really great.

    Choice and Flexibility

    One of the best things about ASP.NET is that most things in it are pluggable. If you find something doesn’t work the way you want it to, you can swap it out for something else.

    The next release of ASP.NET MVC will include a new “Add->View” dialog that makes it easy for you to choose the syntax you want to use when you create a new view template file.  It will allow you to easily select any of of the available view engines you have installed on your machine – giving you the choice to use whichever view approach feels most natural to you:

    AddView9

    Razor will be one of the view engine options we ship built-into ASP.NET MVC.  All view helper methods and programming model features will be available with both Razor and the .ASPX view engine. 

    You’ll also be able to mix and match view templates written using multiple view-engines within a single application or site.  For example, you could write some views using .aspx files, some with .cshtml or .vbhtml files (the file-extensions for Razor files – C# and VB respectively), and some with Spark or NHaml.  You can also have a view template using one view-engine use a partial view template written in another.  You’ll have full choice and flexibility.

    Hello World Sample with Razor

    Razor enables you to start with static HTML (or any textual content) and then make it dynamic by adding server code to it.  One of the core design goals behind Razor is to make this coding process fluid, and to enable you to quickly integrate server code into your HTML markup with a minimum of keystrokes.

    To see a quick example of what I mean by minimizing keystrokes, let’s create a simple “hello world” sample that outputs a message like so:

    image

    Building it with .ASPX Code Nuggets

    If we were to build the above “hello world” sample using ASP.NET’s existing .ASPX markup syntax, we might write it using <%= %> blocks to indicate “code nuggets” within our HTML markup like so:

    image

    One observation to make about this “hello world” sample is that each code nugget block requires 5 characters (<%= %>) to denote the start and stop of the code sequence.  Some of these characters (in particular the % key – which is center top on most keyboards) aren’t the easiest to touch-type.

    Building it with Razor Syntax

    You denote the start of a code block with Razor using a @ character.  Unlike <% %> code nuggets, Razor does not require you to explicitly close the code-block:

    image

    The Razor parser has semantic knowledge of C#/VB code used within code-blocks – which is why we didn’t need to explicitly close the code blocks above.  Razor was able to identify the above statements as self-contained code blocks, and implicitly closed them for us.

    Even in this trivial “hello world” example we’ve managed to save ourselves 12 keystrokes over what we had to type before.  The @ character is also easier to reach on the keyboard than the % character which makes it faster and more fluid to type. 

    Loops and Nested HTML Sample

    Let’s look at another simple scenario where we want to list some products (and the price of each product beside it):

    image

    Building it with .ASPX Code Nuggets

    If we were to implement this using ASP.NET’s existing .ASPX markup syntax, we might write the below code to dynamically generate a <ul> list with <li> items for each product inside it:

    image 

    Building it with Razor Syntax

    Below is how to generate the equivalent output using Razor:

    image

    Notice above how we started a “foreach” loop using the @ symbol, and then contained a line of HTML content with code blocks within it.  Because the Razor parser understands the C# semantics in our code block, it was able to determine that the <li> content should be contained within the foreach and treated like content that should be looped.  It also recognized that the trailing } terminated the foreach statement.

    Razor was also smart enough to identify the @p.Name and @p.Price statements within the <li> element as server code – and execute them each time through the loop. Notice how Razor was smart enough to automatically close the @p.Name and @p.Price code blocks by inferring how the HTML and code is being used together.

    The ability to code like this without having to add lots of open/close markers throughout your templates ends up making the whole coding process really fluid and fast.

    If-Blocks and Multi-line Statements

    Below are a few examples of other common scenarios:

    If Statements

    Like our foreach example above, you can embed content within if statements (or any other C# or VB language construct), without having to be explicit about the code block’s begin/end.  For example:

    image

    Multi-line Statements

    You can denote multiple lines of code by wrapping it within a @{ code } block like so:

    image 

    Notice above how variables can span multiple server code blocks – the “message” variable defined within the multi-line @{ } block, for example, is also being used within the @message code block.  This is conceptually the same as the <% %> and <%= %> syntax within .aspx markup files.

    Multi-Token Statements

    The @( ) syntax enables a code block to have multiple tokens.  For example, we could re-write the above code to concatenate a string and the number together within a @( code ) block:

    image 

    Integrating Content and Code

    The Razor parser has a lot of language smarts built-into it – enabling you to rely on it to do the heavily lifting, as opposed to you having to explicitly do it yourself. 

    Does it break with email addresses and other usages of @ in HTML?

    Razor’s language parser is clever enough in most cases to infer whether a @ character within a template is being used for code or static content.  For example, below I’m using a @ character as part of an email address:

    image

    When parsing a file, Razor examines the content on the right-hand side of any @ character and attempts to determine whether it is C# code (if it is a CSHTML file) or VB code (if it is a VBHTML file) or whether it is just static content.  The above code will output the following HTML (where the email address is output as static content and the @DateTime.Now is evaluated as code:

    image

    In cases where the content is valid as code as well (and you want to treat it as content), you can explicitly escape out @ characters by typing @@.

    Identifying Nested Content

    When nesting HTML content within an if/else, foreach or other block statement, you should look to wrap the inner content within an HTML or XML element to better identify that it is the beginning of a content block.

    For example, below I’ve wrapped a multi-line content block (which includes a code-nugget) with a <span> element:

    image

    This will render the below content to the client – note that it includes the <span> tag:

    image

    You can optionally wrap nested content with a <text> block for cases where you have content that you want to render to the client without a wrapping tag:

    image

    The above code will render the below content to the client – note that it does not include any wrapping tag:

    image 

    HTML Encoding

    By default content emitted using a @ block is automatically HTML encoded to better protect against XSS attack scenarios.

    Layout/MasterPage Scenarios – The Basics

    It is important to have a consistent look and feel across all of the pages within your web-site/application.  ASP.NET 2.0 introduced the concept of “master pages” which helps enable this when using .aspx based pages or templates.  Razor also supports this concept using “layout pages” – which allow you to define a common site template, and then inherit its look and feel across all the views/pages on your site.

    Simple Layout Example

    Below is a simple example of a layout page – which we’ll save in a file called “SiteLayout.cshtml”.  It can contain any static HTML content we want to include in it, as well as dynamic server code.  We’ll then add a call to the “RenderBody()” helper method at the location in the template where we want to “fill in” specific body content for a requested URL:

    image

    We can then create a view template called “Home.cshtml” that contains only the content/code necessary to construct the specific body of a requested page, and which relies on the layout template for its outer content:

    image

    Notice above how we are explicitly setting the “LayoutPage” property in code within our Home.cshtml file.  This indicates that we want to use the SiteLayout.cshtml template as the layout for this view.  We could alternatively indicate the layout file we want to use within a ASP.NET MVC Controller invoking Home.cshtml as a view template, or by configuring it as the default layout to use for our site (in which case we can specify it in one file in our project and have all view templates pick it up automatically).

    When we render Home.cshtml as a view-template, it will combine the content from the layout and sub-page and send the following content to the client:

    image

    Compact, Clean, Expressive Code

    One of the things to notice in the code above is that the syntax for defining layouts and using them from views/pages is clean and minimal.  The code screen-shots above of the SiteLayout.cshtml and Home.cshtml files contain literally all of the content in the two .cshtml files – there is no extra configuration or additional tags, no <%@ Page%> prefix, nor any other markup or properties that need to be set.

    We are trying to keep the code you write compact, easy and fluid.  We also want to enable anyone with a text editor to be able to open, edit and easily tweak/customize them.  No code generation or intellisense required.

    Layout/MasterPage Scenarios – Adding Section Overrides

    Layout pages optionally support the ability to define different “sections” within them that view templates based on the layout can then override and “fill-in” with custom content.  This enables you to easily override/fill-in discontinuous content regions within a layout page, and provides you with a lot of layout flexibility for your site.

    For example, we could return to our SiteLayout.cshtml file and define two sections within our layout that the view templates within our site can optionally choose to fill-in.  We’ll name these sections “menu” and “footer” – and indicate that they are optional (and not required) within our site by passing an optional=true parameter to the RenderSection() helper call (we are doing this using the new C# optional parameter syntax that I’ve previously blogged about).

    image

    Because these two sections are marked as “optional”, I’m not required to define them within my Home.cshtml file.  My site will continue to work fine if they aren’t there. 

    Let’s go back into Home.cshtml, though, and define a custom Menu and Footer section for them.  The below screenshot contains all of the content in Home.cshtml – there is nothing else required in the file.  Note: I moved setting the LayoutPage to be a site wide setting – which is why it is no longer there.

    image

    Our custom “menu” and “footer” section overrides are being defined within named @section { } blocks within the file.  We chose not to require you to wrap the “main/body” content within a section and instead to just keep it inline (which both saves keystrokes and enables you to easily add sections to your layout pages without having to go back through all your existing pages changing their syntax). 

    When we render Home.cshtml as a view-template again, it will now combine the content from the layout and sub-page, integrating the two new custom section overrides in it, and send down the following content to the client:

    image

    Encapsulation and Re-Use with HTML Helpers

    We’ve covered how to maintain a consistent site-wide look and feel using layout pages.  Let’s now look at how we can also create re-usable “HTML helpers” that enable us to cleanly encapsulate HTML generation functionality into libraries that we can re-use across our site – or even across multiple different sites.

    Code Based HTML Helpers

    ASP.NET MVC today has the concept of “HTML Helpers” – which are methods that can be invoked within code-blocks, and which encapsulate generating HTML.  These are implemented using pure code today (typically as extension methods).  All of the existing HTML extension methods built with ASP.NET MVC (both ones we’ve built and ones built by others) will work using the “Razor” view engine (no code changes required):

    image

    Declarative HTML Helpers

    Generating HTML output using a code-only class approach works – but is not ideal.

    One of the features we are looking to enable with Razor is an easy way to create re-usable HTML helpers using a more declarative approach.  Our plan is to enable you to define reusable helpers using a @helper { } declarative syntax like below. 

    image

    You’ll be able to place .cshtml files that contain these helpers into a Views\Helpers directory and then re-use them from any view or page in your site (no extra steps required):

    image

    Note above how our ProductListing() helper is able to define arguments and parameters.  This enables you to pass any parameters you want to them (and take full advantage of existing languages features like optional parameters, nullable types, generics, etc).  You’ll also get debugging support for them within Visual Studio.

    Note: The @helper syntax won’t be in the first beta of Razor – but is something we hope will be enabled with the next drop.  Code-based helpers will work with the first beta.

    Passing Inline Templates as Parameters

    One other useful (and extremely powerful) feature we are enabling with Razor is the ability to pass “inline template” parameters to helper methods.  These “inline templates” can contain both HTML and code, and can be invoked on-demand by helper methods.

    Below is an example of this feature in action using a “Grid” HTML Helper that renders a DataGrid to the client:

    image

    The Grid.Render() method call above is C#.  We are using the new C# named parameter syntax to pass strongly-typed arguments to the Grid.Render method - which means we get full statement completion/intellisense and compile-time checking for the above syntax.

    The “format” parameter we are passing when defining columns is an “inline template” – which contains both custom html and code, and which we can use to customize the format of the data.  What is powerful about this is that the Grid helper can invoke our inline template as a delegate method, and invoke it as needed and as many times as it wants. In the scenario above it will call it each time it renders a row in the grid – and pass in the “item” that our template can use to display the appropriate response.

    This capability will enable much richer HTML helper methods to be developed.  You’ll be able to implement them using both a code approach (like the way you build extension methods today) as well as using the declarative @helper {} approach.

    Visual Studio Support

    As I mentioned earlier, one of our goals with Razor is to minimize typing, and enable it to be easily edited with nothing more than a basic text editor (notepad works great).  We’ve kept the syntax clean, compact and simple to help enable that.

    We have also designed Razor so that you get a rich code editing experience within Visual Studio.  We will provide full HTML, JavaScript and C#/VB code intellisense within Razor based files:

    image

    Notice above how we are providing intellisense for a Product object on the “@p.” code embedded within the <li> element inside a foreach loop.  Also notice how our \Views folder within the Solution Explorer contains both .aspx and .cshtml view templates.  You can use multiple view engines within a single application – making it easy to choose whichever syntax feels best to you.

    Summary

    We think “Razor” provides a great new view-engine option that is streamlined for code-focused templating.  It a coding workflow that is fast, expressive and fun.  It’s syntax is compact and reduces typing – while at the same time improving the overall readability of your markup and code.  It will be shipping as a built-in view engine with the next release of ASP.NET MVC.  You can also drop standalone .cshtml/.vbhtml files into your application and run them as single-pages – which also enables you to take advantage of it within ASP.NET Web Forms applications as well.

    The feedback from developers who have been trying it out the last few months has been extremely positive.  We are going to be shipping the first public beta of it shortly, and are looking forward to your feedback on it.

    Hope this helps,

    Scott

    P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

  • ASP.NET MVC 2 (Release Candidate 2) Now Available

    [In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]

    Earlier this evening the ASP.NET team shipped ASP.NET MVC (Release Candidate 2) for VS 2008/.NET 3.5.  You can download it here.

    The RC2 release of ASP.NET MVC 2 is a follow-up to the first ASP.NET MVC 2 RC build that we shipped in December.  It includes a bunch of bug fixes, performance work, and some final API and behavior additions/changes.  Below are a few of the changes between the RC1 and RC2 release (read the release notes for even more details):

    • The new ASP.NET MVC 2 validation feature now performs model-validation instead of input-validation (this means that when you use model binding all model properties are validated instead of just validations on changed values of a model).  This behavior change was based on extensive feedback from the community.
    • The new strongly-typed HTML input helpers now support lambda expressions which reference array or collection indexes.  This means you can now write code like Html.EditorFor(m=>m.OrdersIdea) and have it correctly output an HTML <input> element whose “name” attribute contains the index (e.g. Orders[0] for the first element), and whose “value” contains the appropriate value.
    • The new templated Html.EditorFor() and Html.DisplayFor() helper methods now auto-scaffold simple properties (and do not render complex sub-properties by default).  This makes it easier to generate automatic scaffolded forms.  I’ll be covering this support in a future blog post.
    • The “id” attribute of client-script validation message elements is now cleaner.  With RC1 they had a form0_ prefix.  Now the id value is simply the input form element name postfixed with a validationMessage string (e.g. unitPrice_validationMessage).
    • The Html.ValidationSummary() helper method now takes an optional boolean parameter which enables you to control whether only model-level validation messages are rendered by it, or whether property level validation messages are rendered as well.  This provides you with more UI customization options for how validation messages are displayed within your UI.
    • The AccountController class created with the default ASP.NET MVC Web Application project template is cleaner.
    • Visual Studio now includes scaffolding support for Delete action methods within Controllers, as well as Delete views (I always found it odd that the default T4 templates didn’t support this before).
    • jQuery 1.4.1 is now included by default with new ASP.NET MVC 2 projects, along with a –vsdoc file that provides Visual Studio documentation intellisense for it.
    • The RC2 release has some significant performance tuning improvements (for example: the lambda based strongly-typed HTML helpers are now much faster).

    Today’s RC2 release only work with VS 2008 and .NET 3.5.  We’ll shortly be releasing the VS 2010 RC (which will be available for everyone to download). It will include ASP. NET MVC 2 support built-in (no separate download required).

    Hope this helps,

    Scott

    P.S. The source code for the ASP.NET MVC RC2 release (along with a MVC futures library that goes with it) can be downloaded here. You can learn even more about ASP.NET MVC 2 by reading the ASP.NET MVC 2 blog series I’m working on.

  • About Technical Debates (and ASP.NET Web Forms and ASP.NET MVC debates in particular)

    [In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]

    Technical debates are discussed endlessly within the blog-o-sphere/twitter-verse, and they range across every developer community. Each language, framework, tool, and platform inevitably has at least a few going on at any particular point in time.

    Below are a few observations I’ve made over the years about technical debates in general, as well as some comments about some of the recent discussions I’ve seen recently about the topic of ASP.NET Web Forms and ASP.NET MVC in particular.

    General Observations About Technical Debates

    Below are a few general observations independent of any specific technical debate:

    a) Developers love to passionately debate and compare languages, frameworks, APIs, and tools.  This is true in every programming community (.NET, Java, PHP, C++, Ruby, Python, etc).  I think you can view these types of religious technical debates in two ways:

    1. They are sometimes annoying and often a waste of time.
    2. They are often a sign of a healthy and active community (since passion means people care deeply on both sides of a debate, and is far better than apathy).

    Personally I think both points are true.

    b) There is never only “one right way” to develop something. As an opening interview question I sometimes ask people to sort an array of numbers in the most efficient way they can.  Most people don’t do well with it.  This is usually not because they don’t know sort algorithms, but rather because they never think to ask the scenarios and requirements behind it – which is critical to understanding the most efficient way to do it.  How big is the sequence of numbers? How random is the typical number sequence (is it sometimes already mostly sorted, how big is the spread of numbers, are the numbers all unique, do duplicates cluster together)? How parallel is the computer architecture?  Can you allocate memory as part of the sort or must it be constant?  Etc. These are important questions to ask because the most efficient and optimal way to sort an array of numbers depends on understanding the answers. 

    Whenever people assert that there is only “one right way” to a programming problem they are almost always assuming a fixed set of requirements/scenarios/inputs – which is rarely optimal for every scenario or every developer.  And to state the obvious - most problems in programming are far more complex than sorting an array of numbers.

    c) Great developers using bad tools/frameworks can make great apps. Bad developers using great tools/frameworks can make bad apps. Be very careful about making broad assumptions (good or bad) about the quality of the app you are building based on the tools/frameworks used.

    d) Developers (good and bad) can grow stronger by stretching themselves and learning new ideas and approaches.  Even if they ultimately don’t use something new directly, the act of learning it can sharpen them in positive ways.

    e) Change is constant in the technology industry.  Change can be scary.  Whether you get overwhelmed by change, though, ultimately comes down to whether you let yourself be overwhelmed.  Don’t stress about having to stop and suddenly learn a bunch of new things - rarely do you have to. The best approach to avoid being overwhelmed is to be pragmatic, stay reasonably informed about a broad set of things at a high-level (not just technologies and tools but also methodologies), and have the confidence to know that if it is important to learn a new technology, then your existing development skills will mostly transition and help.  Syntax and APIs are rarely the most important thing anyway when it comes to development – problem solving, customer empathy/engagement, and the ability to stay focused and disciplined on a project are much more valuable.

    f) Some guidance I occasionally give people on my team when working and communicating with others:

    1. You will rarely win a debate with someone by telling them that they are stupid - no matter how well intentioned or eloquent your explanation of their IQ problems might be.
    2. There will always be someone somewhere in the world who is smarter than you - don’t always assume that they aren’t in the room with you.
    3. People you interact with too often forget the praise you give them, and too often remember a past insult -  so be judicious in handing them out as they come back to haunt you later. 
    4. People can and do change their minds - be open to being persuaded in a debate, and neither gloat nor hold it against someone else if they also change their minds.

    g) I always find it somewhat ironic when I hear people complain about programming abstractions not being good.  Especially when these complaints are published via blogs – whose content is displayed using HTML, is styled with CSS, made interactive with JavaScript, transported over the wire using HTTP, and implemented on the server with apps written in higher-level languages, using object oriented garbage collected frameworks, running on top of either interpreted or JIT-compiled byte code runtimes, and which ultimately store the blog content and comments in relational databases ultimately accessed via SQL query strings.  All of this running within a VM on a hosted server – with the OS within the VM partitioning memory across kernel and user mode process boundaries, scheduling work using threads, raising device events using signals, and using an abstract storage API fo disk persistence.  It is worth keeping all of that in mind the next time you are reading a “ORM vs Stored Procedures” or “server controls – good/bad?” post.  The more interesting debates are about what the best abstractions are for a particular problem.

    h) The history of programming debates is one long infinite loop – with most programming ideas having been solved multiple times before.  And for what it’s worth – many of the problems we debate today were long ago solved with LISP and Smalltalk.  Ironically, despite pioneering a number of things quite elegantly, these two languages tend not be used much anymore. Go figure.

    Some Comments Specific to ASP.NET Web Forms / ASP.NET MVC debates:

    Below are a few comments specific to some of the recent debates that I’ve seen going around within the community as to whether a ASP.NET Web Forms or ASP.NET MVC based approach is best:

    a) Web Forms and MVC are two approaches for building ASP.NET apps. They are both good choices. Each can be the “best choice” for a particular solution depending on the requirements of the application and the background of the team members involved. You can build great apps with either.  You can build bad apps with either. You are not a good or bad developer depending on what you choose. You can be absolutely great or worthless using both.

    b) The ASP.NET and Visual Studio teams are investing heavily in both Web Forms and MVC.  Neither is going away.  Both have major releases coming in the months ahead.  ASP.NET 4 includes major updates to Web Forms (clean ClientIDs and CSS based markup output, smaller ViewState, URL Routing, new data and charting controls, new dynamic data features, new SEO APIs, new VS designer and project improvements, etc, etc).  ASP.NET 4 will also ship with ASP.NET MVC 2 which also includes major updates (strongly typed helpers, model validation, areas, better scaffolding, Async support, more helper APIs, etc, etc).  Don’t angst about either being a dead-end or something you have to change to.  I suspect that long after we are all dead and gone there will be servers somewhere on the Internet still running both ASP.NET Web Forms and ASP.NET MVC based apps.

    c) Web Forms and MVC share far more code/infrastructure/APIs than anyone on either side of any debate about them ever mentions - Authentication, Authorization, Membership, Roles, URL Routing, Caching, Session State, Profiles, Configuration, Compilation, .aspx pages, .master files, .ascx files, Global.asax, Request/Response/Cookie APIs, Health Monitoring, Process Model, Tracing, Deployment, AJAX, etc, etc, etc.  All of that common stuff you learn is equally valid regardless of how you construct your UI.  Going forward we’ll continue to invest heavily in building core ASP.NET features that work for both Web Forms and MVC (like the URL Routing, Deployment, Output Caching, and DataAnnotations for Validation features we are adding with ASP.NET 4). 

    d) I often find debates around programming model appropriateness and abstractions a little silly. Both Web Forms and MVC are programming web framework abstractions, built on top of a broader framework abstraction, programmed with higher level programming languages, running on top of a execution engine abstraction that itself is running on top of a giant abstraction called an OS.  What you are creating with each is HTML/CSS/JavaScript (all abstractions persisted as text, transmitted over HTTP – another higher level protocol abstraction). 

    The interesting question to debate is not whether abstractions are good or not – but rather which abstractions feels most natural to you, and which map best to the requirements/scenarios/developers of your project.

    e) We are about to do a pretty major update to the www.asp.net site.  As part of that we will be posting more end to end tutorials/content (for both Web Forms and MVC).  We will also be providing tutorials and guidance that will help developers quickly evaluate both the Web Forms and MVC approach, easily learn the basics about how both work, and quickly determine which one feels best for them to use. This will make it easy for developers new to ASP.NET, as well as developers who already know either Web Forms or MVC, to understand and evaluate the two approaches and decide which they want to use.

    f) Decide on a project about whether you want to use Web Forms or MVC and feel good about it.  Both can be good choices.  Respect the choices other people make – the choice they have made is also hopefully a good one that works well for them.  Keep in mind that in all likelihood they know a lot more about their own business/skills than you do.  Likewise you hopefully know a lot more about your own business/skills than they do.

    g) Share ideas and best practices with others.  That is a big part of what blogs, forums, listservs and community is all about.  What makes them work great is when people know that their ideas aren’t going to be ripped to shreds, and that they will be treated with respect.  Be constructive, not snarky. Teach, don’t lecture. Remember there is always someone else out there who you can also learn from.

    Hope this helps,

    Scott

  • ASP.NET MVC 2: Strongly Typed Html Helpers

    [In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]

    This is the first in a series of blog posts I’m doing on the upcoming ASP.NET MVC 2 release.  This blog post covers the new strongly-typed HTML helpers added with ASP.NET MVC 2.

    Existing HTML Helper Methods

    ASP.NET MVC 1 shipped with a set of HTML helper methods that can be used within view templates to help with the generation of HTML UI.  For example, to output a textbox you could write code (within your .aspx view template) using the Html.TextBox() helper method below:

    image

    The first parameter to the helper method above supplies the name/id for the textbox, and the second parameter specifies the value it should have.  The helper method above would then render HTML like below back to a browser:

    image

    New Strongly-Typed HTML Helper Methods

    One of the common feature asks people had for ASP.NET MVC 2 was for us to also support strongly-typed HTML helpers that use lambda expressions when referencing models/viewmodels passed to a view template.  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.

    New strongly-typed HTML helper methods are now built-into ASP.NET MVC 2.  These methods use a "Html.HelperNameFor()” naming convention. For example: Html.TextBoxFor(), Html.CheckBoxFor(), Html.TextAreaFor(), etc.  They support using a lambda expression to specify both the name/id of the element, as well as the value to render for it.

    For example, using ASP.NET MVC 2 we can now use the new Html.TextBoxFor() helper in addition to the Html.TextBox() helper above:

    image

    Notice above how we do not need to specify the “ProductName” string parameter anymore – lambda expressions are flexible enough that we can retrieve both the name of the property/field on our model object in addition to its value.

    Because the HTML helpers are strongly-typed, we also get full intellisense support for them within Visual Studio when writing the lambda expression:

    image

    The HTML rendered is the same as the late-bound version of our HTML helper shown previously:

    image

    List of Strongly-Typed HTML Helper Methods built-into ASP.NET MVC 2

    ASP.NET MVC 2 has built-in support for the following strongly-typed HTML helpers:

    HTML Element Helpers:

    • Html.TextBoxFor()
    • Html.TextAreaFor()
    • Html.DropDownListFor()
    • Html.CheckboxFor()
    • Html.RadioButtonFor()
    • Html.ListBoxFor()
    • Html.PasswordFor()
    • Html.HiddenFor()
    • Html.LabelFor()

    Other Helpers:

    • Html.EditorFor()
    • Html.DisplayFor()
    • Html.DisplayTextFor()
    • Html.ValidationMessageFor()

    I’ll be covering the new Html.EditorFor() and Html.DisplayFor() helper methods in a later blog post in this series when I cover the improved auto-scaffold functionality in ASP.NET MVC 2.  We’ll also be using the Html.ValidationMessageFor() helper in my next blog post in this series which covers the improved validation support within ASP.NET MVC 2.

    Strongly-Typed HTML Helpers within Scaffolding

    VS 2008 and VS 2010 both by default now use the new strongly-typed HTML helpers when “scaffolding” new strongly-typed view tempates using the “Add View” command. 

    For example, let’s assume we had a simple “ProductsController” class like below that has an “Edit” action method that renders an edit form for a “Product” model class:

    image

    We can right-click within the Edit action method using Visual Studio and choose the “Add View” context menu command to create a view template.  We’ll choose to create an “Edit” template that is scaffolded using a Product object:

    image

    With ASP.NET MVC 2, the view template that is created by default now uses the new strongly typed HTML helper methods to reference the Product model object:

    image

    Summary

    The strongly-typed HTML helpers included with ASP.NET MVC 2 provide a nice way to get better type-safety within your view templates.  This enables better compile-time checking of your views (allowing you to find errors at build-time instead of at runtime), and also supports richer intellisense when editing your view templates within Visual Studio.

    Hope this helps,

    Scott

  • ASP.NET MVC 2

    [In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]

    Over the last six months the ASP.NET team has been steadily releasing preview, then beta, and now release candidate builds of ASP.NET MVC 2.

    Given that the final release is not too far away, I thought it was a good time to start a new multi-part ASP.NET MVC 2 blog series that discusses the new features and how best to take advantage of them.

    ASP.NET MVC 2

    We shipped ASP.NET MVC 1.0 last March.  Since then, almost 1 million developers have downloaded and used the final release, and its popularity has steadily grown month over month.

    ASP.NET MVC 2 is the next significant update of ASP.NET MVC. It is a compatible update to ASP.NET MVC 1 – so all the knowledge, skills, code, and extensions you already have with ASP.NET MVC continue to work and apply going forward. Like the first release, we are also shipping the source code for ASP.NET MVC 2 under an OSI-compliant open-source license.

    ASP.NET MVC 2 Features

    ASP.NET MVC 2 adds a bunch of new capabilities and features.  I’ll cover them in a lot more depth with this blog series.  Some of them include:

    • New Strongly Typed HTML Helpers (posted: Jan 10th, 2010)
    • Enhanced Model Validation support across both server and client (posted: Jan 15th, 2010) 
    • Auto-Scaffold UI Helpers with Template Customization (post coming soon)
    • Support for partitioning large applications into “Areas” (post coming soon)
    • Asynchronous Controllers support (post coming soon)
    • Support for rendering sub-sections of a page/site using Html.RenderAction (post coming soon)
    • Lots of new helper functions, utilities, and API enhancements (post coming soon)
    • Improved Visual Studio tooling support (post coming soon)

    How to download ASP.NET MVC 2

    ASP.NET MVC 2 is designed to work with both VS 2008 / .NET 3.5, as well as with VS 2010 / .NET 4.  Supporting both versions means that you can start using it today without having to wait to upgrade to VS2010 / .NET 4.

    Click here to download the ASP.NET MVC 2 release candidate for .NET 3.5 and VS 2008.  It can be installed side-by-side with ASP.NET MVC 1.0 on the same machine.

    ASP.NET MVC 2 is a built-in component of VS 2010 / .NET 4 – which means you will not have to download or install anything to get it once you install any version of Visual Studio 2010.  The current public VS 2010 Beta 2 release includes the ASP.NET MVC 2 Preview 2 release.  The upcoming VS 2010 Release Candidate that will be available for download next month will have a more recent ASP.NET MVC 2 RC built-in.

    ASP.NET Web Forms + ASP.NET MVC

    We are always careful to make clear that ASP.NET MVC is an option with ASP.NET.  ASP.NET Web Forms continues to be the most widely used approach when building applications with ASP.NET, and the new ASP.NET 4 release contains significant improvements for ASP.NET Web Forms development (clean client IDs and CSS based control markup, better viewstate management, new data and charting controls, URL routing, SEO improvements, and much more).  You can learn more about these improvements within my ongoing VS 2010 and .NET 4 blog series.

    We’ll be improving and enhancing both the ASP.NET Web Forms and ASP.NET MVC programming models even further in future releases. Developers can and should choose to use whichever model feels most comfortable and natural to them. We’ll be publishing new videos and guidance on the www.asp.net shortly that helps provide additional guidance about each and how to pick the one that feels most comfortable to you. 

    Hope this helps,

    Scott

  • My Presentations in Europe (December 2009)

    This past week I’ve been traveling around Europe giving a bunch of presentations (approximately 5 hours in each country) – Norway on Tuesday, Sweden on Wednesday, Denmark on Thursday, and Belgium on Friday.  I’ll then be presenting at the BizSpark Camp in France this coming Tuesday.

    Things went well with the talks, and I had fun meeting lots of new people (more than 3,000 attended the talks!). Below is a picture of my talk in Belgium – where everyone showed up in a red shirt :-)

    belgium

    Download Talks

    My talks were filmed in a few locations – and I’ll update this post with pointers to the videos once they are online to watch.

    Below are copies of my slides + demos bits:

    Hope this helps,

    Scott

    P.S. In addition to blogging, I’m also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

  • ASP.NET MVC V2 Preview 1 Released

    The ASP.NET team just released the first public preview of ASP.NET MVC Version 2.  You can download it here.

    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. 

    Summary

    Click here to download a .zip file that contains a ASP.NET MVC 2 project that implements the sample code I demonstrated in the above walkthrough.

    Today’s build of ASP.NET MVC 2 is just a first preview.  More features will be coming in future previews, and the team expects to get a lot of feedback on ways to improve and enhance the release. 

    The goal with doing these regular previews is to help make sure that this feedback process is open and that anyone who wants to participate can easily get involved.  Please post any feedback, suggestions or problems you have to the ASP.NET MVC Forum on www.asp.net.  You can also learn more about the release from Phil Haack’s MVC2 post, and from the Channel9 video Phil did with Scott Hanselman about the Preview 1 release.

    Hope this helps,

    Scott

    P.S. I have been using Twitter more recently to-do quick posts and share links.  You can follow me on Twitter at: http://www.twitter.com/scottgu (@scottgu is my twitter name)

  • June 7th Links: ASP.NET, AJAX, ASP.NET MVC, Visual Studio

    Here is the latest in my link-listing series.  Also check out my ASP.NET Tips, Tricks and Tutorials page and Silverlight Tutorials page for links to popular articles I've done myself in the past.

    You can also now follow me on twitter (@scottgu) where I also post links and small posts.

    ASP.NET

    • GridView Confirmation Box using jQuery: Mohammed Azam has a nice post that describes how to implement model confirmation UI using jQuery.  This is particularly useful for scenarios like saving or deleting data.

    AJAX

    • ASP.NET 4.0 AJAX – Client Templates: Damien White has a great post that describes the new client templating support in ASP.NET AJAX.  This provides an easy and powerful way to dynamically create rich HTML UI on the client.

    • ASP.NET 4.0 AJAX - Data Binding: Damien White continues his great ASP.NET AJAX series with this article that describes the new client-side data binding features in the new version of ASP.NET AJAX. 

    ASP.NET MVC

    • DataAnnotations and ASP.NET MVC: Brad Wilson (a dev on the ASP.NET MVC team) has a nice post that describes how to use DataAnnotations to annotate model objects, and then use a model binder to automatically validate them when accepting form posted input.  DataAnnotation support will be built-in with the next version of ASP.NET MVC.

    Visual Studio

    Hope this helps,

    Scott

  • May 30th Links: ASP.NET, AJAX, ASP.NET MVC, Visual Studio

    Here is the latest in my link-listing series.  Also check out my ASP.NET Tips, Tricks and Tutorials page and Silverlight Tutorials page for links to popular articles I've done myself in the past. 

    You can also now follow me on twitter (@realscottgu) where I also post links and small posts.

    ASP.NET

    AJAX

    • Automatically Minify and Combine JavaScript in Visual Studio: Dave Ward has a great article that describes how you can add a build command to Visual Studio that enables you to automatically compress and combine client-side JavaScript files.  This makes your pages load faster on the client and improves the perceived performance of your sites.

    • Client-side Data Binding in ASP.NET AJAX 4.0: Fritz Onion has a great article about the new client-side templating features of ASP.NET AJAX 4.0 (which you can download and use today in .NET 3.5 projects).  This enables powerful client data-binding scenarios against JSON based data.  Also check out Politian’s Blog to find some great tutorials on how to use it.

    ASP.NET MVC

    • Visual Studio NUnit Templates for ASP.NET MVC: The VS Web Tools team has released updated NUnit templates that work with ASP.NET MVC 1.0.  This enables you to automatically create a test project that uses NUnit instead of MSTest when you do a File->New Project and select the ASP.NET MVC 1.0 Project item.

    • Custom Route Constraints in ASP.NET MVC: Keyvan Nayyeriu has a nice post that discusses how to create a custom route constraint in ASP.NET MVC (one of the extensibility points in Simone’s list above).  You can use these to control whether a route rule is used or not, and they can enable some pretty rich routing scenarios.  Note that in addition to creating route constraint classes, ASP.NET MVC also supports using Regular Expressions and HTTP Method filters to constrain routes as well. Keyvan is the co-author with Simone of the Beginning ASP.NET MVC Book (free chapter available).

    Visual Studio

    Hope this helps,

    Scott

  • Free ASP.NET MVC “NerdDinner” Tutorial Now in HTML

    Last month I blogged about a free end-to-end ASP.NET MVC tutorial called “NerdDinner” that I wrote for the Professional ASP.NET MVC 1.0 book from Wrox Press.  The book is now released and shipping on Amazon

    The NerdDinner tutorial walks through how to build a small, but complete, application using ASP.NET MVC, and introduces some of the core concepts behind it.  You can download a PDF version of the tutorial here.

    NerdDinner Tutorial Now Also Available in HTML

    A few minutes ago I finished publishing an HTML version of the NerdDinner tutorial as well.  You can read it online for free here.

    I split the tutorial up across 12 segments to make it more manageable to read.  I also increased the sizes of the screenshots, and used a really nifty syntax highlighter that Scott Hanselman helped set me up with.  I actually find the end result a lot easier to read than the PDF version.

    Below are links to the different NerdDinner tutorial segments:

    Hope this helps,

    Scott

  • ASP.NET MVC 1.0

    mvcsource[1] Two weeks ago at MIX we released ASP.NET MVC 1.0.  ASP.NET MVC is a free, fully supported, Microsoft product that enables developers to easily build web applications using a model-view-controller pattern.  ASP.NET MVC provides a “closer to the metal” web programming option for ASP.NET.  It enables full control over HTML markup and URL structure, and facilitates unit testing and a test driven development workflow.

    Releasing the ASP.NET MVC source code under MS-PL

    I’m excited today to announce that we are also releasing the ASP.NET MVC source code under the Microsoft Public License (MS-PL).  MS-PL is an OSI-approved open source license.  The MS-PL contains no platform restrictions and provides broad rights to modify and redistribute the source code.  You can read the text of the MS-PL at: http://www.opensource.org/licenses/ms-pl.html

    Learning more about ASP.NET MVC

    To learn more about ASP.NET MVC, you can read my free ASP.NET MVC PDF tutorial that covers building an end-to-end application (starting literally with File->New Project).

    There were a number of great ASP.NET MVC talks at MIX this year.  Below are links to several of them:

    There are also several great ASP.NET MVC tutorials at http://www.asp.net/mvc.  You can also read the ASP.NET MVC MSDN Documentation.

    Download ASP.NET MVC

    Click here to download and install ASP.NET MVC 1.0.  You can also install it using the new Microsoft Web Platform Installer V2 – which provides an integrated setup experience for the entire Microsoft web stack.

    The ASP.NET MVC 1.0 source code is now available.  Scroll down to the bottom of the ASP.NET MVC download page and you’ll find links to both the ASP.NET MVC 1.0 integrated MSI setup, as well as a .zip file that contains the ASP.NET MVC source code.  The ASP.NET MVC source code includes a VS 2008 project file that enables you to build it.

    Hope this helps,

    Scott

  • Free ASP.NET MVC eBook Tutorial

    bookcover[1] There has been a lot of excitement in the community about the new ASP.NET MVC framework that is about to ship (literally any day now – announcement coming soon).  As with anything new, people are also asking for more tutorials/samples/documentation that cover how to get started and build applications with it.

    Over the last few months I’ve been helping to contribute to an ASP.NET MVC book that Scott Hanselman, Rob Conery, and Phil Haack have been writing for Wrox.  The book is now in production, and will be available to buy in stores soon (you can pre-order it on Amazon today).

    I wrote the first chapter of the book – which is a 185 page end-to-end tutorial that walks-through building a small, but complete, ASP.NET MVC application from scratch.  The agreement I made with Wrox was that I’d write it for free in return for them also making it available as a free PDF download.

    I’m excited to announce that you can now download this free end-to-end tutorial chapter (it is a 14mb PDF file). It’s licensed under a “Creative Commons Attribution No Derivatives” license – which means you can share, distribute, print, or hand it out to anyone.

    NerdDinner ASP.NET MVC Tutorial

    The tutorial starts by using the File->New Project command in Visual Studio to create a brand new ASP.NET MVC project, and then incrementally adds functionality and features.  Along the way it covers how to:

    • Create a database
    • Build a model with validation and business rules
    • Implement data listing/details UI on a site using Controllers and Views
    • Enable CRUD (Create, Update, Delete) data form entry
    • Use the ViewModel pattern to pass information from a Controller to a View
    • Re-use UI across a site using partials and master pages
    • Implement efficient data paging
    • Secure an application using authentication and authorization
    • Use AJAX to deliver dynamic updates
    • Use AJAX to add interactive map support
    • Perform automated unit testing (including dependency injection and mocking)

    The application the tutorial builds is called “NerdDinner”. It provides an easy way for people to organize, host and search for new topic-based dinners online:

    nerddinner_small[1]

    Scott Hanselman has been hosting NerdDinners for years, and came up with the idea of building the tutorial around an application that facilitates this.  He is also now hosting a live custom-skinned version of the application at www.nerddinner.com)

    Download Links

    Hope this helps,

    Scott

    P.S. The book is entering production now and so is officially in un-edited status (meaning professional editors haven’t gone through it yet).  We’ll update the PDF with any important edits once the text is final.

    P.P.S. And yes – this is one of the reasons my blog has been more quiet than normal the last few months.  Expect more regular blog posting again soon once I recover from this. :-)

  • ASP.NET MVC Design Gallery and Upcoming View Improvements with the ASP.NET MVC Release Candidate

    Today we launched a new ASP.NET MVC Design Gallery on the www.asp.net site.  The design gallery hosts free HTML design templates that you can download and easily use with your ASP.NET MVC applications.  Included with each design template is a Site.master file, a CSS stylesheet, and optionally a set of images, partials, and helper methods that support them. 

    The gallery allows you to preview each of the designs online, as well as download a .zip version of them that you can extract and integrate into your site.  The gallery allows anyone to create and submit new designs under the creative commons license.  Visitors to the gallery can vote to provide feedback on them (thumbs up/thumbs down).  The most popular designs show up at the top of the gallery. 

    We think this will provide a useful way for developers to more easily create attractive, standards compliant, sites.  It will also hopefully encourage folks to create and share designs that can be easily re-used by others.

    Upcoming View Improvements with the Release Candidate

    While on the topic of UI, I thought I'd also share a few details about some of the View-related improvements that are coming with the new ASP.NET MVC Release Candidate build that will be shipping shortly.  In addition to bug fixes, the RC incorporates a number of view-specific feature additions and community suggestions.

    Views without Code-Behind Files

    Based on feedback from a lot of people, we've decided to make a change so that MVC view files by default do not have code-behind files. This change helps to reinforce the purpose of views in a MVC world (which are intended to be purely about rendering and to not contain any non-rendering related code), and for most people eliminates unused files in the project:

    With the ASP.NET MVC Beta, developers could eliminate the code-behind file by using the CLR syntax for generic types in a view's inherits attribute, but that CLR syntax is (to put it mildly) pretty undiscoverable and hard to use.  The ASP.NET MVC team was able to combine a few extensibility features already in ASP.NET to now enable the standard VB/C# language syntax within the inherits attribute with the ASP.NET RC build:

    One other nice benefit of not using a code-behind file is that you'll now get immediate intellisense when you first add them to the project.  With the beta you had to do a build/compile immediately after creating a view in order to get code intellisense within it.  The RC makes the workflow of adding and immediately editing a view compile-free and much more seamless.

    Top-Level Model Property on Views

    With previous builds of ASP.NET MVC, you accessed the strongly typed model object passed to the view using the ViewData.Model property:

    The above syntax still works, although now there is also a top-level "Model" property on ViewPage that you can use:

    This property does the same thing as the previous code sample - its main benefit is that it allows you to write the code a little more concisely.

    HTML/AJAX Helpers Now Enable Expression Syntax

    One of the requests a few people have asked for is the ability to use strongly-typed expression syntax (instead of using strings) when referring to the Model when using a View's HTML and AJAX helper objects.

    With the beta build of ASP.NET MVC this wasn't possible, since the HtmlHelper and AjaxHelper helper classes didn't expose the model type in their signature, and so people had to build helper methods directly off of the ViewPage<TModel> base class in order to achieve this.  The ASP.NET MVC RC build introduces new HtmlHelper<TModel> and AjaxHelper<TModel> types that are exposed on the ViewPage<TModel> base class.  These types now allow anyone to build strongly-typed HTML and AJAX helper extensions that use expression syntax to refer to the View's model.

    For example, I could build a (very simple) strongly-typed "TextBox" helper method using the code below:

    And then use it within any of my views to bind against a Product model object like so:

    Visual Studio will provide full intellisense for the strongly-typed expression syntax when working against the View's model in the source editor in this way:

     

    Note: the HTML helper extensions in the core ASP.NET MVC V1 assembly will still use the existing (non-expression based) syntax.  We are then planning to add expression-based versions to the MVCFutures assembly. You can of course also add your own helper methods (using either strings or strongly-typed BLOCKED EXPRESSION.  All of the built-in helper methods can also optionally be removed (because they are extension methods) if you want to replace or override them with your own.

    Scaffolding Support

    The ASP.NET MVC RC build includes automatic "UI scaffolding" support when creating views using the new ASP.NET MVC "Add View" command inside Visual Studio.  The scaffolding support enables the automatic generation of views against any .NET type or object - meaning it can work against POCO classes, LINQ to SQL, LINQ to Entities, NHibernate, SubSonic, LLBLGen Pro, or any other object model. The scaffolding engine uses reflection to retrieve the public shape of a View's model type, and then passes it to a scaffolding template to populate appropriate markup based on it within the view being created.

    For example, assume we have a ProductsController class and want to create an "Edit" action on it to display an edit view of a particular Product.  Using the RC build we can right-click within our "Edit" action method and choose the "Add View" context menu command like so:

    Within the "Add View" dialog we can then indicate that we are passing a "Product" type to our View:

    We can indicate that we want an "Empty" view template created (like above), or indicate that we want VS to automatically scaffold a form "Edit" view for the Product object we are supplying:

    If we choose the "Edit" template VS will automatically generate a file for us that has the appropriate HTML and validation helpers to create an editable form view:

    We can then run the application and immediately get edit UI:

    We can then go in and change the generated edit.aspx file however we want to tweak/customize it. 

    One of the really nice things about the scaffolding system we are shipping is that it is implemented using Visual Studio's built-in T4 code generation system (Scott Hanselman has a nice post about this here).  The "List", "Edit", "Create" and "Details" templates we ship with ASP.NET MVC can all be completely customized or replaced with T4 templates of your own (or downloaded from the ASP.NET MVC Design Gallery). So if you have your own particular way of creating HTML, or want to use custom HTML helpers (for example: strongly-typed expression based ones) you can update the default templates and the scaffolding system will use them going forward. 

    We are planning to enable the templates to be overriden both on a machine-wide level, as well as on a per-project level (so that you can check-in application-specific scaffolding templates under source control and share them across a team).

    MSBuild Task for Compiling Views

    By default when you do a build on an ASP.NET MVC project it compiles all code within the project, except for the code within view files.  With the ASP.NET MVC Beta you had to roll your own MSBuild task if you wanted to compile the views.  The ASP.NET MVC RC build now includes a built-in MSBuild task that you can use to include views as part of the project compilation process.  This will verify the syntax and code included inline within all views and master pages for the application, and give you build errors if it encounters any problems.

    For performance reasons we don't recommend running this for quick compiles during development, but it is convenient to add to particular build configuration profiles (for example: staging and deployment) and/or for use with Build or CI (continuous integration) servers.

    Other ASP.NET MVC Release Candidate features coming

    Above is a short list of some of the view-specific functionality coming with the release candidate build. 

    There are many other features and requests coming with the RC as well including: IDataErrorInfo support to enable models to surface validation error messages, as well as richer error validation extensibility to enable you to use your own approach to surface model validation errors to ModelBinders (the IDataErrorInfo support is built on top of this); new FileResult and JavaScriptResult ActionResult types (allowing you to more easily download files as well as executable JavaScript to browsers); built-in jQuery -vsdoc intellisense support; refactored AccontController support to enable easier unit testing and extensibility with form login scenarios; a variety of project template improvements, more extensibility everywhere; lots of bug fixes; and a few other cool features I'll blog about later once the RC is out.

    We'll be releasing the ASP.NET MVC Release Candidate in January.  Our plan is to have that build be ASP.NET MVC V1 API and feature-complete and have zero known bugs.  We'll give people a short period to upgrade to it, give it a good tire-kicking, and report any last minute issues they find.  We'll then ship the official V1 release shortly after that (so not far off now).

    Hope this helps,

    Scott

More Posts Next page »

This Blog

Syndication

Powered by Community Server, by Telligent Systems
'