asp.net-mvc - 通过方法属性进行 ASP.NET MVC 路由

标签 asp.net-mvc routes url-routing decorator

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/

相关文章:

xss - ASP.NET MVC XSS 验证

asp.net-mvc - 使用 OpenID 的 ASP.NET MVC 多站点 SSO

angular - 如何在没有插件的情况下平滑滚动到 Angular 4 中的页面 anchor ?

javascript - 防止 :blank tab from opening, 应该立即将用户直接发送到指定的 URL

asp.net - Page.RouteData.Values 对于一个页面是空的,而不是另一个页面

asp.net-mvc - datatype.text 验证什么?

c# - 使用初始化器访问对象的属性

php - 没有命名参数的 Symfony 通配符主机路由

node.js - 如何在 Node.js 中使用 Socket.io 从客户端发送到路由文件

php - 相同的路线但在 Laravel 5.1 路由中调用不同的 Controller