2

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?

danludwig
  • 46,965
  • 25
  • 159
  • 237

1 Answers1

2

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".

fengd
  • 7,551
  • 3
  • 41
  • 44
  • I don't think I can use PUT as the form method. I use @Html.BeginForm to render the form, and its arguments take an enum of either Post or Get. Isn't there something in the http spec about browser forms only supporting post and get? – danludwig Feb 02 '12 at 18:17
  • 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 – fengd Feb 03 '12 at 02:39
  • Right, I knew it was the action method selector (see original question title). So I should have both POST and PUT? – danludwig Feb 03 '12 at 10:31
  • if you don't add "POST" constraint, then the route would not match. To the routing module, it's a POST request, not PUT yet. – fengd Feb 03 '12 at 14:23