使用 mvc 路由约束,因此 url 只能映射到三个可能的参数之一

Posted

技术标签:

【中文标题】使用 mvc 路由约束,因此 url 只能映射到三个可能的参数之一【英文标题】:using mvc route constraints so a url can only be mapped to one of three possible params 【发布时间】:2012-03-17 05:38:18 【问题描述】:

这是我的路线:

routes.MapRoute(null, "myaccount/monitor/category", // Matches
                new  controller = "MyAccount", action = "Monitor", category = (string)null 
);

我想添加一个约束,以便类别只能匹配空值或三个参数之一(即概述、投影、历史记录)

【问题讨论】:

我个人更喜欢使用三个独立的路由而不是使用路由约束。 【参考方案1】:

Gaby 发布的内联 Regex 可以正常工作。另一种方法是定义一个自定义 IRouteConstraint:

public class FromValuesListConstraint : IRouteConstraint

    private List<string> _values;

    public FromValuesListConstraint(params string[] values)
    
        this._values = values.Select(x => x.ToLower()).ToList();
    

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    
        string value = values[parameterName].ToString();

        if (string.IsNullOrWhiteSpace(value))
        
            return _values.Contains(string.Empty);
        

        return _values.Contains(value.ToLower());
    

然后将约束的实例传递给您的 MapRoute 调用:

routes.MapRoute(null,
    "myaccount/monitor/category", // Matches
new  controller = "MyAccount", action = "Monitor", category = UrlParameter.Optional  ,
new  category = new FromValuesListConstraint ("overview", "projection", "history", string.Empty) 
        );

【讨论】:

【参考方案2】:

您可以使用UrlParameter.Optional 来允许空值,也可以使用MapRoute method 的constraints 参数..

 routes.MapRoute(null,
                      "myaccount/monitor/category", // Matches
                      new  controller = "MyAccount", action = "Monitor", category = UrlParameter.Optional  ,
                      new  category = "overview|projection|history"
            );

【讨论】:

【参考方案3】:

我认为您可能必须使用单独的路线:

routes.MapRoute("Monitor",
                      "myaccount/monitor", // Matches
                      new  controller = "MyAccount", action = "Monitor" 
            );

routes.MapRoute("MonitorHistory",
                      "myaccount/monitor/history", // Matches
                      new  controller = "MyAccount", action = "Monitor", category = "history" 
            );

routes.MapRoute("MonitorOverview",
                      "myaccount/monitor/overview", // Matches
                      new  controller = "MyAccount", action = "Monitor", category = "overview" 
            );

routes.MapRoute("MonitorProjection",
                      "myaccount/monitor/projection", // Matches
                      new  controller = "MyAccount", action = "Monitor", category = "projection" 
            );

或者,您可能想要执行以下操作:

routes.MapRoute("MonitorGlobal",
                      "myaccount/monitor/category", // Matches
                      new  controller = "MyAccount", action = "Monitor", category = string.Empty 
            );

然后在你的控制器中:

public ActionResult Monitor(string category)

    switch (category)
    
        case string.Empty:
            // do something
            break;

        case "overview":
            // do something
            break;

        // so on and so forth

        default:
            // no match, handle accordingly
            break;
    

【讨论】:

以上是关于使用 mvc 路由约束,因此 url 只能映射到三个可能的参数之一的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 asp.net mvc 中的公共路由之前先映射特殊路由?

asp.net mvc 路由约束正则表达式

如何使用 MVC 路由多语言 URL

ASP.NET MVC学习之路由篇

asp.net mvc 之旅—— 第三站 路由模板中强大的自定义IRouteConstraint约束

运用路由约束 使用属性路由 精通ASP-NET-MVC-5-弗瑞曼