Wednesday, August 6, 2008

ASP.NET MVC & REST

Make that 4 too many acronyms...my apologies.

I'm crazy about REST. It appeals to me in a number of ways and it's the primary reason behind my interest in ASP.NET MVC. I didn't know a thing about REST prior to Ruby on Rails v2.0 but then again I wasn't a web programmer prior to that. Now that I'm building web applications on a regular basis, I've been drawn to REST and Rails concepts.

Which brings me to the topic of this post: REST on ASP.NET MVC (MSMVC)! It turns out that the MSMVC framework is very capable of following REST principles. The routing engine supports constraints based on HTTP methods and it's a no-brainer to also support overloaded POST. Here's a simple constraint to support a hidden _method form input:
public class FormMethodConstraint : IRouteConstraint {
string _method;

public FormMethodConstraint(string method) {
if (String.IsNullOrEmpty(method))
throw new ArgumentException("method cannot be null or empty.", "method");
_method = String.Format("^{0}$", method);
}

public bool Match(System.Web.HttpContextBase httpContext,
Route route, string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection) {
var vals = httpContext.Request.Form.GetValues("_method");
if (vals == null) return false;

foreach (var val in vals)
if (Regex.IsMatch(val, _method, RegexOptions.IgnoreCase)) return true;
return false;
}
}


With this class, you can write routes that support overloaded POST:
source.MapRoute(
"FormDestroy",
"{controller}/{id}",
new { action = "Destroy" },
new { httpMethod = new HttpMethodConstraint("POST"),
formMethod = new FormMethodConstraint("DELETE") }
);


Now, you can put a hidden input in your form with the name _method and the value DELETE and when the form is sent back the server, it will route to the Destroy() action on your controller!

There's more RESTful goodness to come from me, I'm just getting started! :)

No comments: