我怎样才能实现“自然” ASP.NET MVC 中的 url 方案路由表

发布于 2024-10-17 10:50:20 字数 768 浏览 7 评论 0原文

我想指定我的路由表,这样它们会感觉更“自然”,

/Products
/Product/17
/Product/Edit/17
/Product/Create

接近默认配置,但“索引”操作将映射到控制器名称的倍数形式和< em>“详细信息” 操作将直接与控制器名称后面的项目 ID 进行映射。

我知道我可以通过显式定义特殊的路由映射来实现这一点,如下所示:

routes.MapRoute(
    "ProductsList",
    "Products",
    new { controller = "Product", action = "Index" }
);
routes.MapRoute(
    "ProductDetails",
    "Product/{id}",
    new { controller = "Product", action = "Details" }
);

/*
 * Ditto for all other controllers
 */

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

上面的代码对我来说太冗长了,而且缺点是每个控制器需要至少提及两次才能普遍应用此 url 模式。

有什么方法可以概括这一点,或者在这种情况下我必须从事体力劳动吗?

I would like to specify my routing tables such that they would feel much more "natural"

/Products
/Product/17
/Product/Edit/17
/Product/Create

Close to the defaults configuration but such that "Index" action would be mapped to the multiples form of the controller name and "Details" action would be mapped directly with an id of the item directly following the controller name.

I know I can achieve this by explicitly defining special routing mappings like this:

routes.MapRoute(
    "ProductsList",
    "Products",
    new { controller = "Product", action = "Index" }
);
routes.MapRoute(
    "ProductDetails",
    "Product/{id}",
    new { controller = "Product", action = "Details" }
);

/*
 * Ditto for all other controllers
 */

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

The code above is way too verbose for my tastes and has the downside that each controller needs to be mentioned at least twice to prevasively apply this url pattern.

Is there some way to generalize this or am I bound to manual labour in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

多情出卖 2024-10-24 10:50:20

您可以尝试这样的操作:

routes.MapRoute(
                "ProductsList",
                "{pluralizedControllerName}",
                new { controller = "Home", action = "Index" },
                new { pluralizedControllerName = new PluralConstraint() }
                );

            routes.MapRoute(
                "ProductDetails",
                "{controller}/{id}",
                new { controller = "Home", action = "Details" },
                new { id = @"\d+" }
            );

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

注意第二条路线中的约束,它确保 /Product/Create 不会被第二条路线选择,以便它被映射为第三条路线。

对于路由测试,您可以使用 routedebugger,并用于编写路由的单元测试尝试 MvcContrib-TestHelper。您可以通过 NuGet 获取这两者。

编辑:

您可以使用此 简单复数器,然后实现如下所示:

public class PluralConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            List<string> names = GetControllerNames();//get all controller names from executing assembly
            names.ForEach(n => n.Pluralize(n));
            return names.Contains(values[parameterName]);
        }
    }

You can try something like this:

routes.MapRoute(
                "ProductsList",
                "{pluralizedControllerName}",
                new { controller = "Home", action = "Index" },
                new { pluralizedControllerName = new PluralConstraint() }
                );

            routes.MapRoute(
                "ProductDetails",
                "{controller}/{id}",
                new { controller = "Home", action = "Details" },
                new { id = @"\d+" }
            );

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

Notice the constraint in second route, it ensures that /Product/Create doesn't get picked by second route so that it gets mapped as third.

For route testing you can use routedebugger, and for writing unit test for routes try MvcContrib-TestHelper. You can get both with NuGet.

EDIT:

You can use this simple pluralizer and then implement something like this:

public class PluralConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            List<string> names = GetControllerNames();//get all controller names from executing assembly
            names.ForEach(n => n.Pluralize(n));
            return names.Contains(values[parameterName]);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文