在 StackOverflow Podcast #54 ,Jeff 提到他们通过处理路由的方法上方的属性在 StackOverflow 代码库中注册 URL 路由。听起来是一个不错的概念(菲尔·哈克(Phil Haack)提出了关于路线优先级的警告)。
有人可以提供一些示例来实现这一点吗?
此外,使用这种路由方式有什么“最佳实践”吗?
最佳答案
更新:此内容已发布于 codeplex 。完整的源代码以及预编译的程序集可供下载。我还没有时间在网站上发布文档,所以现在这篇文章就足够了。
更新:我添加了一些新属性来处理 1) 路由排序、2) 路由参数约束和 3) 路由参数默认值。下面的文字反射(reflect)了此更新。
我实际上已经为我的 MVC 项目做了类似的事情(我不知道 Jeff 是如何使用 stackoverflow 来做到这一点的)。我定义了一组自定义属性:UrlRoute、UrlRouteParameterConstraint、UrlRouteParameterDefault。它们可以附加到 MVC Controller 操作方法,以使路由、约束和默认值自动绑定(bind)到它们。
用法示例:
(请注意,此示例有些人为,但它演示了该功能)
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();
}
UrlRouteAttribute 定义:
/// <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; }
}
UrlRouteParameterConstraintAttribute 定义:
/// <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 函数的一次调用来替换对 MapRoute 的调用:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteUtility.RegisterUrlRoutesFromAttributes(routes);
}
RouteUtility.RegisterUrlRoutesFromAttributes 的定义:
完整来源位于 codeplex 。如果您有任何反馈或错误报告,请访问该网站。
关于asp.net-mvc - 通过方法属性进行 ASP.NET MVC 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/894779/