Question

Given the following route:

context.MapRoute(null, "widgets", 
    new { controller = "Widgets", action = "Add" }, 
    new { httpMethod = new HttpMethodConstraint("PUT") });

And the following controller:

public class WidgetsController
{
    [HttpPut]
    public ActionResult Add(WidgetForm model)
    {
        return DoStuff(); // code here doesn't matter
    }
}

And a view that renders the following form (using HtmlHelper.@Html.HttpMethodOverride(HttpVerbs.Put):

<form action="/widgets" method="post">
    <!-- many form elements, then -->
    <input name="X-HTTP-Method-Override" type="hidden" value="PUT" />
</form>

When the form is submitted, the MVC action method selector does not choose the above action method. If I set a breakpoint on the opening brace, it is never hit. In browser, it returns 404 page (I believe this is the default ActionNotFound behavior).

However, the action method selector does choose the Add HttpPut method with the following route:

context.MapRoute(null, "widgets", 
    new { controller = "Widgets", action = "Add" }, 
    new { httpMethod = new HttpMethodConstraint("PUT", "POST") });

This doesn't seem right... is it? It seems to me that I should be able to do this without a POST constraint. The action method is not decorated with HttpPost, so why should the POST constraint be necessary?

Was it helpful?

Solution

Its right. Looking a bit deeper into how this works in the MVC pipeline it's actually MVC (ActionMethodSelectorAttribute, ActionInvoker,RedirectToRoute) that handles this and not the RouteModule.

So in route module, it's still a "POST" request, not a "PUT".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top