Handling MVC2 variables with hyphens in their name

2019-04-27 17:38发布

I'm working with some third-party software that creates querystring parameters with hyphens in their names. I was taking a look at this SO question and it seems like their solution is very close to what I need but I'm too ignorant to the underlying MVC stuff to figure out how to adapt this to do what I need. Ideally, I'd like to simply replace hyphens with underscores and that would be a good enough solution. If there's a better one, then I'm interested in hearing it.

An example of a URL I want to handle is this:

http://localhost/app/Person/List?First-Name=Bob&My-Age=3

with this Controller:

public ActionResult List(string First_Name, int My_Age)
{
    {...}
}

To repeat, I cannot change the querystring being generated so I need to support it with my controller somehow. But how?

For reference, below is the custom RouteHandler that is being used to handle underscores in controller names and action names from the SO question I referenced above that we might be able to modify to accomplish what I want:

public class HyphenatedRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler  GetHttpHandler(RequestContext requestContext)
    {
        requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
        requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");
        return base.GetHttpHandler(requestContext);
    }
}

2条回答
The star\"
2楼-- · 2019-04-27 18:07

Have you tried [Bind(Prefix="First-name")]? It might work...

One way would be with a custom model binder. Another way would be with an action filter. Use the model binder if you want to do this on a specific type. Use the action filter if you want to do this on a specific action or controller. So for the latter method you could do something like:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var keys = filterContext.HttpContext.Request.QueryString.AllKeys.Where(k => k.Contains('-'));
        foreach(var k in keys)
        {
            filterContext.ActionParameters.Add(
                new KeyValuePair<string, object>(
                    k.Replace('-', '_'), filterContext.HttpContext.Request.QueryString[k]));
        }
        base.OnActionExecuting(filterContext);
    }
查看更多
Fickle 薄情
3楼-- · 2019-04-27 18:27

I had the same problem. In the end rather than doing something too complex I just get the query string parameters using

string First_Name = Request["First-Name"];

You may want to check for NUlls incase the parameter is not there, but this sorted it out for me. You can also include an optional parameter for the ActionResult for test purposes etc..

查看更多
登录 后发表回答