Reputation: 21713
Is there a way in ASP.NET MVC 4 to bind route values from sources other than a placeholder in a route URL: a header or post data for example? Or are they intrinsically coupled to the URL?
Specifically, I was interested in overriding the action
route value with a value from a posted form field. That way, you could easily have different submit buttons on a page that invoked different actions on the controller by giving each a name
of action
and a value
of the action name.
I've tried setting the RouteData.Values
in an HttpModule
but that appears to be too early in the pipeline to override the action.
Upvotes: 1
Views: 82
Reputation: 49095
HttpModule
is indeed too early for this, and is actually not needed. You can rely on the regular MVC route-handling mechanism and simply provide it with your own RouteValues
extracted from the HTTP request.
For example:
public class MyHeadersBasedRoute : RouteBase
{
public const string HEADER_CONTROLLER_KEY = "X-REQUESTED-CONTROLLER";
public const string HEADER_ACTION_KEY = "X-REQUESTED-ACTION";
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var requestedController = httpContext.Request.Headers[HEADER_CONTROLLER_KEY];
var requestedAction = httpContext.Request.Headers[HEADER_ACTION_KEY];
if (String.IsNullOrEmpty(requestedController) || String.IsNullOrEmpty(requestedAction))
return null;
var ret = new RouteData(this, new MvcRouteHandler());
ret.Values.Add("controller", requestedController);
ret.Values.Add("action", requestedAction);
// add any extra parameter from request, for example:
ret.Values.Add("id", httpContext.Request.Form["id"]);
return ret;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
Then just register it in your global.asax
:
RouteTable.Routes.Add(new MyHeadersBasedRoute());
Upvotes: 1