MVC路由问题

时间:2011-04-07 18:43:04

标签: asp.net-mvc asp.net-mvc-3

我想按如下方式设置路由:

/个人资料/编辑 - >路线到编辑动作

/个人资料/添加 - >添加操作的路线

/个人资料/用户名 - >使用参数username路由到Index操作,因为操作用户名不存在。

所以我希望将第二个参数解析为控制器操作,除非不存在具有该名称的控制器;然后它应该路由到默认索引页面并使用url部分作为id。

可能的?

4 个答案:

答案 0 :(得分:2)

您可以在路线限制中使用正则表达式,如此

routes.MapRoute(
    "UserProfileRoute",
    "Profile/{username}",
    new { controller = "Profile", action = "Index" },
    new { username = "(?i)(?!edit$|add$)(.*)" });

这会匹配/profile/addendum /profile/someusername等网址,并会忽略/profile/edit/profile/add

答案 1 :(得分:0)

一切皆有可能。但是,为什么不只是制作/描述你的根?

如果无法做到这一点,您可能需要对操作路线进行硬编码。

答案 2 :(得分:0)

以下是实现此目的的一种方法:

在Global.asax.cs中创建这些路线:

 routes.MapRoute("UserProfileRoute", "Profile/{username}",
    new { controller = "Profile", action = "Index" });
 routes.MapRoute("DefaultProfileRoute", "Profile/{action}", 
    new { controller = "Profile", action = "SomeDefaultAction" });

这将按预期匹配/ Profile / someUsername。但它将失败所有其他行动。现在假定所有动作名称都是用户名。快速解决此问题的方法是在第一条路线上添加IRouteConstraint:

 routes.MapRoute("UserProfileRoute", "Profile/{username}", 
     new { controller = "Profile", action = "Index" }, 
     new { username = new NotAnActionRouteConstraint() });
 routes.MapRoute("DefaultProfileRoute", "Profile/{action}", 
    new { controller = "Profile", action = "SomeDefaultAction" });

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

                    // it is likely parameterName is not cased correctly,
                    // something that would need to be 
                    // addressed in a real implementation
        return typeof(ProfileController).GetMethod(parameterName,
                         BindingFlags.Public | BindingFlags.Instance) == null;
    }
 }

然而,这有点难看。希望有人知道更好的解决方案。

当您的某个用户选择与操作相同的名称时,您也会遇到问题:)

答案 3 :(得分:0)

马特的解决方案可以让你获得90%的胜利。但是,不使用路由约束来排除操作名称,而是使用路由约束来仅包含有效的用户名,如下所示:

public class MustMatchUserName : IRouteConstraint 
{ 

    private Users _db = new UserEntities(); 

    public MustMatchUserName() 
    { } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
        return _db.Users.FirstOrDefault(x => x.UserName.ToLower() == values[parameterName].ToString().ToLower()) != null; 
    } 
} 

然后,正如Matt所指出的那样,在用户创建过程中,您必须强制执行一个规则,即您的ActionNames对用户名无效。

counsellorben