使用名称中的连字符处理MVC2变量

时间:2010-05-06 15:14:20

标签: asp.net-mvc-2 asp.net-mvc-routing

我正在使用一些第三方软件,这些软件会在名称中创建带有连字符的查询字符串参数。我正在看this SO question,看起来他们的解决方案非常接近我的需求,但我对基础MVC的东西太无知了,想弄清楚如何调整它来做我需要的东西。理想情况下,我想简单地用下划线替换连字符,这将是一个很好的解决方案。如果有一个更好的,那么我有兴趣听到它。

我想要处理的URL的一个例子是:

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

使用此控制器:

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

重复一遍,我无法更改正在生成的查询字符串,所以我需要以某种方式支持它与我的控制器。但是如何?

作为参考,下面是用于处理控制器名称和操作名称中的下划线的自定义RouteHandler,我在上面引用的SO问题中可以修改以完成我想要的操作:

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 个答案:

答案 0 :(得分:7)

你试过[Bind(Prefix="First-name")]吗?它可能有用......

一种方法是使用自定义模型绑定器。另一种方法是使用动作过滤器。如果要对特定的类型执行此操作,请使用模型绑定器。如果要在特定的操作或控制器上执行此操作,请使用操作过滤器。因此对于后一种方法,您可以执行以下操作:

    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);
    }

答案 1 :(得分:1)

我遇到了同样的问题。最后,我只是使用

获取查询字符串参数,而不是做太复杂的事情
string First_Name = Request["First-Name"];

你可能想检查NUlls,因为参数不在那里,但这对我来说是一个很好的选择。您还可以为ActionResult包含一个可选参数以用于测试目的等。