我想设置路由如下:MVC路由问题
/资料/编辑 - >路线编辑行动
/资料/添加 - >路线添加动作
/资料/用户名 - >使用参数username输入索引操作的路由,因为操作用户名不存在。
所以我想第二个参数被解析为控制器动作,除非没有该名称的控制器存在;那么它应该路由到默认的索引页面并使用url部分作为id。
可能吗?
我想设置路由如下:MVC路由问题
/资料/编辑 - >路线编辑行动
/资料/添加 - >路线添加动作
/资料/用户名 - >使用参数username输入索引操作的路由,因为操作用户名不存在。
所以我想第二个参数被解析为控制器动作,除非没有该名称的控制器存在;那么它应该路由到默认的索引页面并使用url部分作为id。
可能吗?
马特的解决方案可以让你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;
}
}
然后,马特指出,在用户创建过程中,你必须强制执行规定您的ActionNames对用户名无效。
counsellorben
任何事情都是可能的。但是,为什么不直接制作/剖析你的根?
如果这是不可能的,你可能需要硬编码你的动作的路线。
这里是实现这个的一种方法:
请在Global.asax.cs中你这些路线:
routes.MapRoute("UserProfileRoute", "Profile/{username}",
new { controller = "Profile", action = "Index" });
routes.MapRoute("DefaultProfileRoute", "Profile/{action}",
new { controller = "Profile", action = "SomeDefaultAction" });
预期这将匹配/资料/ 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;
}
}
但是,这有点难看。希望有人知道更好的解决方案。
也有问题,当你的用户挑选一个名称相同的动作:)
您可以使用正则表达式在你的路由约束,像这样
routes.MapRoute(
"UserProfileRoute",
"Profile/{username}",
new { controller = "Profile", action = "Index" },
new { username = "(?i)(?!edit$|add$)(.*)" });
将匹配的URL像/profile/addendum
/profile/someusername
并忽略/profile/edit
和/profile/add
嗯,是的,有种愚蠢的,但我我真的没想到:)我可能会这样做,这会让事情变得更容易。 – Jasper 2011-04-07 20:34:45