在Jeff的StackOverflow Podcast #54中,Jeff提到他們通過處理路由的方法上方的屬性在StackOverflow代碼庫中註冊了他們的URL路由。聽起來像一個很好的概念(Phil Haack提出關於路線優先權的警告)。通過方法屬性的ASP.NET MVC路由
有人可以提供一些樣品,使這種情況發生?
此外,使用此類路由的任何「最佳實踐」?
在Jeff的StackOverflow Podcast #54中,Jeff提到他們通過處理路由的方法上方的屬性在StackOverflow代碼庫中註冊了他們的URL路由。聽起來像一個很好的概念(Phil Haack提出關於路線優先權的警告)。通過方法屬性的ASP.NET MVC路由
有人可以提供一些樣品,使這種情況發生?
此外,使用此類路由的任何「最佳實踐」?
UPDATE:這已經張貼在codeplex。完整的源代碼以及預編譯的程序集都可以下載。我還沒有時間在網站上發佈文檔,所以這個SO帖子現在已經足夠了。
更新:我添加了一些新的屬性來處理1)路由排序,2)路由參數約束和3)路由參數默認值。以下文字反映了此更新。
我實際上爲我的MVC項目做了這樣的事情(我不知道Jeff是如何用stackoverflow做的)。我定義了一組自定義屬性:UrlRoute,UrlRouteParameterConstraint,UrlRouteParameterDefault。可以將它們附加到MVC控制器操作方法,以使路由,約束和默認值自動綁定到它們。
實例:
(注意這個例子是人爲但它說明的特徵)UrlRouteAttribute的
public class UsersController : Controller
{
// Simple path.
// Note you can have multiple UrlRoute attributes affixed to same method.
[UrlRoute(Path = "users")]
public ActionResult Index()
{
return View();
}
// Path with parameter plus constraint on parameter.
// You can have multiple constraints.
[UrlRoute(Path = "users/{userId}")]
[UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
public ActionResult UserProfile(int userId)
{
// ...code omitted
return View();
}
// Path with Order specified, to ensure it is added before the previous
// route. Without this, the "users/admin" URL may match the previous
// route before this route is even evaluated.
[UrlRoute(Path = "users/admin", Order = -10)]
public ActionResult AdminProfile()
{
// ...code omitted
return View();
}
// Path with multiple parameters and default value for the last
// parameter if its not specified.
[UrlRoute(Path = "users/{userId}/posts/{dateRange}")]
[UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
[UrlRouteParameterDefault(Name = "dateRange", Value = "all")]
public ActionResult UserPostsByTag(int userId, string dateRange)
{
// ...code omitted
return View();
}
定義:UrlRouteParameterConstraintAttrib的
/// <summary>
/// Assigns a URL route to an MVC Controller class method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteAttribute : Attribute
{
/// <summary>
/// Optional name of the route. If not specified, the route name will
/// be set to [controller name].[action name].
/// </summary>
public string Name { get; set; }
/// <summary>
/// Path of the URL route. This is relative to the root of the web site.
/// Do not append a "/" prefix. Specify empty string for the root page.
/// </summary>
public string Path { get; set; }
/// <summary>
/// Optional order in which to add the route (default is 0). Routes
/// with lower order values will be added before those with higher.
/// Routes that have the same order value will be added in undefined
/// order with respect to each other.
/// </summary>
public int Order { get; set; }
}
定義UTE:
/// <summary>
/// Assigns a constraint to a route parameter in a UrlRouteAttribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterConstraintAttribute : Attribute
{
/// <summary>
/// Name of the route parameter on which to apply the constraint.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Regular expression constraint to test on the route parameter value
/// in the URL.
/// </summary>
public string Regex { get; set; }
}
UrlRouteParameterDefaultAttribute的定義:
/// <summary>
/// Assigns a default value to a route parameter in a UrlRouteAttribute
/// if not specified in the URL.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterDefaultAttribute : Attribute
{
/// <summary>
/// Name of the route parameter for which to supply the default value.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Default value to set on the route parameter if not specified in the URL.
/// </summary>
public object Value { get; set; }
}
更改的Global.asax.cs:
替換以圖路線的呼叫,與該RouteUtility一個電話。 RegisterUrlRoutesFromAttributes功能:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteUtility.RegisterUrlRoutesFromAttributes(routes);
}
RouteUtility.RegisterUrlRoutesFromAttributes的定義:
完整的源代碼可達上codeplex。如果您有任何反饋或錯誤報告,請轉到該網站。
這篇文章只是爲了擴展DSO的答案。
在將我的路由轉換爲屬性時,我需要處理ActionName屬性。所以在GetRouteParamsFromAttribute:
ActionNameAttribute anAttr = methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), false)
.Cast<ActionNameAttribute>()
.SingleOrDefault();
// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
RouteName = routeAttrib.Name,
Path = routeAttrib.Path,
ControllerName = controllerName,
ActionName = (anAttr != null ? anAttr.Name : methodInfo.Name),
Order = routeAttrib.Order,
Constraints = GetConstraints(methodInfo),
Defaults = GetDefaults(methodInfo),
});
我還發現路線的命名不適合。該名稱是使用controllerName.RouteName動態構建的。但我的路由名稱是控制器類中的常量字符串,我使用這些常量也調用Url.RouteUrl。這就是爲什麼我真的需要屬性中的路由名稱作爲路由的實際名稱。
我要做的另一件事是將默認屬性和約束屬性轉換爲AttributeTargets.Parameter,以便我可以將它們粘貼到參數中。
1.下載RiaLibrary.Web.dll並用[URL]它引用在你的ASP.NET MVC的網站項目
2. Decoreate控制器方法屬性:
public SiteController : Controller
{
[Url("")]
public ActionResult Home()
{
return View();
}
[Url("about")]
public ActionResult AboutUs()
{
return View();
}
[Url("store/{?category}")]
public ActionResult Products(string category = null)
{
return View();
}
}
順便說一句,「? 「登錄'{?category}'參數意味着它是可選的。您不需要在默認路徑明確指定這一點,這就是等於這樣的:
routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });
3.更新的Global.asax.cs文件
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoutes(); // This does the trick
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
如何設置默認值,限制?例如:
public SiteController : Controller
{
[Url("admin/articles/edit/{id}", Constraints = @"id=\d+")]
public ActionResult ArticlesEdit(int id)
{
return View();
}
[Url("articles/{category}/{date}_{title}", Constraints =
"date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
public ActionResult Article(string category, DateTime date, string title)
{
return View();
}
}
如何設置排序?例如:
[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
return View();
}
[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
return View();
}
我結合這兩種方法爲Frankensteinian版本,任何人誰想要它。 (我喜歡可選的參數符號,但也認爲它們應該是與默認/約束不同的屬性,而不是全部混合成一個)。
http://github.com/djMax/AlienForce/tree/master/Utilities/Web/
我需要得到ITCloud路由使用AsyncController在asp.net mvc的2個工作 - 這樣做,只是在源編輯RouteUtility.cs類並重新編譯。你必須從動作名稱去掉了「已完成」上線98
// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
RouteName = String.IsNullOrEmpty(routeAttrib.Name) ? null : routeAttrib.Name,
Path = routeAttrib.Path,
ControllerName = controllerName,
ActionName = methodInfo.Name.Replace("Completed", ""),
Order = routeAttrib.Order,
Constraints = GetConstraints(methodInfo),
Defaults = GetDefaults(methodInfo),
ControllerNamespace = controllerClass.Namespace,
});
然後,在AsyncController,與熟悉的UrlRoute
和UrlRouteParameterDefault
屬性裝飾XXXXCompleted的ActionResult:
[UrlRoute(Path = "ActionName/{title}")]
[UrlRouteParameterDefault(Name = "title", Value = "latest-post")]
public ActionResult ActionNameCompleted(string title)
{
...
}
。希望幫助有同樣問題的人。
您也可以嘗試AttributeRouting,它可從github或通過nuget獲得。
這是一個無恥的插件,因爲我是項目作者。但是,如果我不是很高興使用它。你可能也是。 github存儲庫wiki中有大量文檔和示例代碼。
有了這個庫,你可以做很多事情:
我確定還有一些我忘記的東西。一探究竟。通過nuget安裝是無痛的。
注意:自4/16/12起,AttributeRouting還支持新的Web API基礎結構。以防萬一你正在尋找可以處理的東西。 Thanks subkamran!
我想這樣做的屬性可以防止使用路由默認值和路由約束... – 2009-05-22 13:39:20
使用這種方法,我從來不需要默認路由,因爲您將每條路由綁定到特定的方法。你對約束是正確的。我研究了能夠將約束添加爲屬性屬性,但遇到了一個障礙,因爲MVC約束是使用匿名對象指定的,屬性屬性只能是簡單類型。我認爲仍然有可能將約束作爲一個屬性(使用更多的編碼),但是我還沒有打擾它,因爲我到目前爲止還沒有真正需要約束我的MVC工作(我傾向於驗證路由值在控制器中)。 – DSO 2009-05-22 15:53:52
我的意思是默認路徑路徑中的項目,如{username},但我也意識到它們通常是基元。 – 2009-05-22 17:06:27