ASP.NET MVC 4 Beta Released!
Last September at //BUILD/ we announced ASP.NET MVC 4 Developer Preview. Today we're releasing the next release on the road to ASP.NET MVC 4, ASP.NET MVC 4 Beta. This release includes some great new features since the ASP.NET MVC 4 Developer Preview, including the introduction of ASP.NET Web API.
You can get all the info on ASP.NET MVC 4 at http://asp.net/mvc/mvc4
Here's an overview of what's new, and a quick reminder of some of the top features in ASP.NET MVC 4 in general.
ASP.NET Web API
The big new feature since the Developer Preview is the introduction of ASP.NET Web API.
ASP.NET Web API started out as WCF Web API. I've personally been a big fan of Web API - you may have seen my earlier post, WCF MediaTypeProcessor + Speech API = SpeechProcessor fun. I'm excited to see these merge together, as this brings a lot of power to Web API, unites programming models and removes the burden of having to choose between the two.
Why use ASP.NET Web API?
ASP.NET MVC was designed primarily for interacting with humans via web pages. The main use case is emitting HTML and responding to user input (submitting forms, clicking links, etc.). It does a great job at that.
ASP.NET Web API is built for all the other, non-human interactions your site or service needs to support. Think about jQuery code that's making an Ajax request, or a service interface that supports a mobile client. In these cases, the requests are coming from code and expect some kind of structured data and specific HTTP Status Codes.
These two are very complimentary, but different enough that trying to build out HTTP services using ASP.NET MVC took a lot of work to get right. The inclusion of ASP.NET Web API in ASP.NET MVC (and availability elsewhere, including ASP.NET Web Pages) means that you can build top-notch HTTP services in an ASP.NET MVC application, taking advantage of a common base and using the same underlying paradigms. I'm going to quote the release notes (normally something I'd frown on, but since I helped post them I'm going to quote them):
ASP.NET Web API includes support for the following features:
- Modern HTTP programming model: Directly access and manipulate HTTP requests and responses in your Web APIs using a new, strongly typed HTTP object model. The same programming model and HTTP pipeline is symmetrically available on the client through the new HttpClient type.
- Full support for routes: Web APIs now support the full set of route capabilities that have always been a part of the Web stack, including route parameters and constraints. Additionally, mapping to actions has full support for conventions, so you no longer need to apply attributes such as [HttpPost] to your classes and methods.
- Content negotiation: The client and server can work together to determine the right format for data being returned from an API. We provide default support for XML, JSON, and Form URL-encoded formats, and you can extend this support by adding your own formatters, or even replace the default content negotiation strategy.
- Model binding and validation: Model binders provide an easy way to extract data from various parts of an HTTP request and convert those message parts into .NET objects which can be used by the Web API actions.
- Filters: Web APIs now supports filters, including well-known filters such as the [Authorize] attribute. You can author and plug in your own filters for actions, authorization and exception handling.
- Query composition: By simply returning IQueryable<T>, your Web API will support querying via the OData URL conventions.
- Improved testability of HTTP details: Rather than setting HTTP details in static context objects, Web API actions can now work with instances of HttpRequestMessage and HttpResponseMessage. Generic versions of these objects also exist to let you work with your custom types in addition to the HTTP types.
- Improved Inversion of Control (IoC) via DependencyResolver: Web API now uses the service locator pattern implemented by MVC’s dependency resolver to obtain instances for many different facilities.
- Code-based configuration: Web API configuration is accomplished solely through code, leaving your config files clean.
- Self-host: Web APIs can be hosted in your own process in addition to IIS while still using the full power of routes and other features of Web API.
That's a lot of good stuff. I'm going to highlight a few of my favorites.
Full Support For Routes
If you're used to the routing features in ASP.NET, you'll feel right at home with ASP.NET Web API. The routes are defined right where you'd expect in Global.asax. Here's how they look in an ASP.NET MVC application:
routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
One small difference you may have noticed - since ASP.NET Web API is built around the standard HTTP methods, there's no need for an Action - those are inferred from the HTTP Method.
So when you create a new ApiController, it looks like this:
public class ValuesController : ApiController { // GET /api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET /api/values/5 public string Get(int id) { return "value"; } // POST /api/values public void Post(string value) { } // PUT /api/values/5 public void Put(int id, string value) { } // DELETE /api/values/5 public void Delete(int id) { } }
A GET request maps to the Get action, and you don't need to map that anywhere. If found that really easy to work with, and it pushes you to do the right thing as far as building services around the correct HTTP verbs.
Model Binding
Model binding is a powerful feature in ASP.NET MVC (and on its way to Web Forms in ASP.NET 4.5 too). It allows you to write a method that accepts your custom object type as a parameter, and ASP.NET Web API handles mapping posted data to that parameter. It lets you focus on implementing your specifications and get out of the business of mindless (and error prone) mapping code. Here's an example, showing how a method that accepts posted data can focus on the logic of handling the data:
public HttpResponseMessage<comment> PostComment(Comment comment) { comment = repository.Add(comment); var response = new HttpResponseMessage<comment>(comment, HttpStatusCode.Created); response.Headers.Location = new Uri(Request.RequestUri, "/api/comments/" + comment.ID.ToString()); return response; }
Filters
Filters are a really powerful feature in ASP.NET MVC. You can use attributes to apply pre/post logic to action methods, entire controllers, or globally to all action methods. They're available in ASP.NET Web API as well, and you use the same kind of logic to both build and apply them. I worked with a sample that applied some custom attribute based validation using a global action filter, and found it really to apply my ASP.NET MVC background.
Content Negotiation
Content Negotiation is the process by which clients (e.g. your web browser) and servers decide on content formats. Clients send accept headers which tell the server what content type they prefer - XML, JSON, VCard, iCal, image, audio, custom formats, etc. - and the server supplies the best fit for each client's requested formats automatically. This actually happens all the time, on each page you request, without you knowing or caring about it.
ASP.NET Web API has this built in, so a simple one line Web API action method will return either XML or JSON depending on what the client requests, without your needing to do anything to support it. I wrote about the general idea in detail in my WCF MediaTypeProcessor + Speech API = SpeechProcessor fun example, which showed returning audio data if the client supports it. The API's changed, but the concept is the same, because it's built on standard content negotiation standards.
ASP.NET Web API Content
There's a lot more to say about ASP.NET Web API, so we've built out a new ASP.NET Web API content area on the ASP.NET site which includes some documentation and an introductory screencast series.
You can see a full presentation on ASP.NET Web API from Daniel Roth (PM for ASP.NET MVC and ASP.NET Web API) at last week's C4MVC meeting here:
Bundling by default
Another new very useful feature since the developer preview is the use of Bundling in the ASP.NET project templates. The <head> section of the _Layout.cshtml in a new ASP.NET MVC 4 Beta project looks like this now:
<head> <meta charset="utf-8" /> <title>@ViewBag.Title - My ASP.NET MVC Application</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" rel="stylesheet" type="text/css" /> <link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/themes/base/css")" rel="stylesheet" type="text/css" /> <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script> <meta name="viewport" content="width=device-width" /> </head>
There's no need to call out each individual script or CSS file, because the referenced scripts are all automatically bundled and minified.
One nice advantage of this that may not be immediately obvious is that this removes the hardcoded JavaScript references from the templates. For example, in the past, updating jQuery in an ASP.NET MVC application was a two step process:
- Grab the latest jQuery version from NuGet
- Search through my views for hardcoded references to the old jQuery version and update them to the new version
Now that bundling is handling scripts in the /Scripts folder, that second step is automatic.
Razor Enhancements
There are few nice enhancements to Razor (so they'll work in ASP.NET Web Pages 2 as well) that simplify some common scenarios.
URL Resolution - Support for ~/ syntax
Instead of writing this:
<script src="@Url.Content("~/Scripts/Site.js")"></script>
You can now write this:
<script src="~/Scripts/Site.js"></script>
Razor understands the ~/ syntax and automatically resolves it with all standard HTML attributes.
Conditional attribute rendering
If you have an attribute that might be null, in the past you've needed to do a null check to avoid writing out an empty attribute, like this:
<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div>
Now Razor is able to handle that automatically, so you can just write out the attribute. If it's null, the attribute isn't written:
<div class="@myClass">Content</div>
So if @myClass is null, the output is just this:
<div>Content</div>
Again, this is a Razor feature, so it's shared with ASP.NET Web Pages 2.
NuGet Based Project Installation
When you create a new ASP.NET MVC 4 project, you'll notice that a bunch of NuGet packages are being installed. That's because the project template heavily leverages the NuGet package restore feature - in fact, even ASP.NET MVC 4 is a NuGet package.
ASP.NET MVC installation has been taking increasing advantage of including NuGet pagkages in Visual Studio templates with each release, and while the AspNetMvc package actually came out with the ASP.NET MVC 4 Developer Preview, the Beta buys into it even more.
This makes it easy to take advantage of the NuGet Package Restore feature, which enables you to leverage NuGet without having to commit your binary dependencies to source control.
Software Requirements and Installation
The ASP.NET MVC 4 components for Visual Studio require PowerShell 2.0 and either Visual Studio 2010 with Service Pack 1 or Visual Web Developer Express 2010 with Service Pack 1. The ASP.NET MVC 4 Beta doesn't work with the Developer Previews of Visual Studio 11 or .NET 4.5. Stand by for those.
ASP.NET MVC 4 Beta runs side by side with previous versions of ASP.NET MVC. It's a pretty lightweight install - I've installed and uninstalled it lots of times without any impact on my other ASP.NET projects or Visual Studio in general.
You can install ASP.NET MVC 4 via Web PI or using the standalone installer executable - both are available at http://www.asp.net/mvc/mvc4
In the EULA (found at %ProgramFiles(x86)%\Microsoft ASP.NET\ASP.NET MVC 4\eula.rtf after install), you'll see that section 1a includes a Go Live license providing you meet the terms listed. I am not a lawyer, I am not a dentist, read the EULA, etc., but it does include this text: "If you comply with the rest of these license terms, you may also distribute to third parties or deploy for third parties to access over the Internet the ASP.NET programs that you develop using the software, provided that..."
Update: Where to learn more about ASP.NET MVC 4 and ASP.NET Web API
ASP.NET Site Content
The best way to keep up with upcoming ASP.NET releases is at http://asp.net/vnext - that's where we put all the videos, links to new tutorials, and information about downloads. If you just remember one URL, that's the one.
We've started offering a dedicated page for each new ASP.NET MVC version. In addition to the installers and top links, they have some nice bullet points you can send to your boss to convince them to let you upgrade. :-)
There's a lot of ASP.NET Web API specific content, including tutorials and a six part screencast series there. It's also got a link to the ASP.NET Web API Forum, the best place to get questions answered by the ASP.NET Web API team.
Scott Guthrie presentation on ASP.NET MVC 4 at TechDays
Scott Guthrie announced ASP.NET MVC 4 at TechDays 2012 in the Netherlands. The video's now up on Channel 9.
Herding Code: Brad Wilson on ASP.NET MVC 4
I interviewed Brad Wilson (member of the ASP.NET team and co-author of Wrox Professional ASP.NET MVC 3) for the Herding Code podcast.
Download / Listen:
Herding Code 134: Brad Wilson on ASP.NET 4 Beta and ASP.NET Web API
Feedback and Help
While I'm always happy for blog comments, there are better places to go to leave feedback or get help.
To get help (often directly from the ASP.NET team), you can use the forums:
The best way to report bugs is via Connect. Honest, these route right into the team's bug database.
The best place for suggestions (not bugs) is on the ASP.NET MVC UserVoice page. While it's probably late in the cycle to get big suggestions into ASP.NET 4, it's great time to start shaping the next version ASP.NET MVC.