Resources Over MVC – Simple Clients Part 2

November 9, 2011 23:31 by Admin

Simple Clients Part 1 explained how introducing the MapRomRoute extension methods from the the Resources Over MVC (ROM) assembly allows simple User Agents to request resources in a particular format using a query string parameter. This post looks at how the same extension also allows User Agents to “Overload” the POST method if they don’t support the full range of HTTP Methods.

Overload POST

Not all User Agents support the all HTTP Methods. For example, with Flash, if you want to set the Authentication headers (e.g. if you want to use Basic Authentication) then you can only use the POST method. You can’t even use the GET method! Also, most browsers only support GET and POST. DELETE requests may fail to reach a web service due to infrastructure restrictions, for instance a firewall may be configured to only permit GET and POST requests through.

One common solution is to “Overload” POST requests. A de-facto standard seems to be growing out of Ruby on Rails whereby a POST request is made with an additional query string parameter in the URI (or possibly in the entity body). The additional parameter is often _method=delete.

When you use the MapRomRoute extension method introduced in the last post, another feature it enables is POST overloading. It supports a number of techniques for the User Agent to specify which HTTP Method the web service should substitute for the POST method (listed here in priority order):

  • Provide a custom header with the replacement method as the value
  • Provide a form value with the replacement method as the value
  • Provide a query string parameter with the replacement method as the value

For each of these the default name is "X-Http-Method-Override". So using any of the following three requests would cause the web service to act as if a DELETE had been sent:

Custom Header:

   POST http://mymachine/services/products/34 HTTP/1.0
Accept: application/xml
   X-Http-Method-Override: DELETE
Host: mymachine
 
Form Value:
   POST http://mymachine/services/products/34?X-Http-Method-Override=DELETE HTTP/1.0
Accept: application/xml
Host: mymachine


X-Http-Method-Override=DELETE
 

Query String Parameter:

   POST http://mymachine/services/products/34?X-Http-Method-Override=DELETE HTTP/1.0
Accept: application/xml
Host: mymachine

If you don’t like the to use “X-Http-Method-Override” as the name of the header, form value or query string parameter, you can change it by setting the appropriate property on application start up (i.e. in the Application_Start method in Global.asax):

   RomHttpRequestWrapper.XHttpMethodOverrideHeader = "Method-Override";
   RomHttpRequestWrapper.HttpMethodOverrideFormId = "methodOverride";
   RomHttpRequestWrapper.HttpMethodOverrideQueryStringId = "_method";

 

But Doesn’t ASP.Net MVC Supports Overloading Already?

Yes, it is true that since version 2.0, ASP.Net MVC does support POST overloading natively. You can use either a custom header, form variable or a query string parameter called “X-HTTP-Method-Override" to dictate which method you want to be used. I have two issues with their implementation though.

Firstly, you must name your header / variable / parameter "X-HTTP-Method-Override", which as mentioned above, is not the convention used by other popular frameworks. There is no way to change the name.

Secondly, for some reason, which I would love to know, the code that performs the override finishes with these statements:

if (verbOverride != null) {
    if (!String.Equals(verbOverride, "GET", StringComparison.OrdinalIgnoreCase) &&
        !String.Equals(verbOverride, "POST", StringComparison.OrdinalIgnoreCase)) {
        incomingVerb = verbOverride;
    }
}
return incomingVerb;

This means that if the value of the override is GET or POST, then it is ignored. Why do this? It seems superfluous in the case of POST and restrictive in the case of GET. So in the case of Flash, you cannot GET resources whilst using Authentication! Perhaps, the ASP.Net MVC team were taking a leaf out of Apple’s book? ;-)

What Next?

The sample is available here: Samples.WebService.zip (4.39 mb)

The next few blogs will explain more of the features the ROM assembly supports.


Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading