我想設置路由如下: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