通用 ASP.NET MVC 路由冲突

发布于 2024-10-09 17:45:50 字数 1208 浏览 0 评论 0原文

我正在开发旧版 ASP.NET 系统。我说遗留是因为系统的 90% 左右都没有测试。我正在尝试修复此项目中的路线,但遇到了我希望用通用路线解决的问题。

我有以下路线:

        routes.MapRoute(
             "DefaultWithPdn",
             "{controller}/{action}/{pdn}",
             new { controller = "", action = "Index", pdn = "" },
             null
         );

        routes.MapRoute(
           "DefaultWithClientId",
           "{controller}/{action}/{clientId}",
           new { controller = "", action = "index", clientid = "" },
           null
       );

问题是第一条路线正在捕获我需要路由到第二条路线的所有流量。该路由是通用的(任一路由定义中的约束中都没有定义控制器),因为整个应用程序中的多个控制器共享相同的前提(有时我们需要“pdn”,有时我们需要“clientId”)。

我如何映射这些通用路线,以便它们到达正确的控制器和操作,但又不会太贪婪?或者我可以吗?这些路线是否太通用了(我开始相信就是这种情况)。

此时我唯一的选择(据我所知)是以下之一:

在约束中,应用正则表达式来匹配操作值,例如: (foo|bar|biz|bang) ,对于控制器也是如此: (home|customer|产品)每个控制器。但是,这有一个问题,因为我可能需要这样做:

~/Foo/Home/123 // Should map to "DefaultwithPdn"

~/Foo/Home/abc // Should map to "DefaultWithClientId"

这意味着如果 Foo 控制器有一个采用 pdn 的操作和另一个采用 clientId 的操作(此应用程序中经常发生这种情况),则选择了错误的路由。

将这些约束硬编码到每个可能的控制器/动作组合中对我来说似乎有很多重复,而且我感觉我已经研究这个问题太久了,所以我需要另一双眼睛来帮忙。

我可以有通用路线来处理这种情况吗?或者我是否需要为每个控制器设置自定义路由,并将约束应用于这些路由上的操作?

谢谢

I'm working on a Legacy ASP.NET system. I say legacy because there are NO tests around 90% of the system. I'm trying to fix the routes in this project and I'm running into a issue I wish to solve with generic routes.

I have the following routes:

        routes.MapRoute(
             "DefaultWithPdn",
             "{controller}/{action}/{pdn}",
             new { controller = "", action = "Index", pdn = "" },
             null
         );

        routes.MapRoute(
           "DefaultWithClientId",
           "{controller}/{action}/{clientId}",
           new { controller = "", action = "index", clientid = "" },
           null
       );

The problem is that the first route is catching all of the traffic for what I need to be routed to the second route. The route is generic (no controller is defined in the constraint in either route definition) because multiple controllers throughout the entire app share this same premise (sometimes we need a "pdn" sometimes we need a "clientId").

How can I map these generic routes so that they go to the proper controller and action, yet not have one be too greedy? Or can I at all? Are these routes too generic (which is what I'm starting to believe is the case).

My only option at this point (AFAIK) is one of the following:

In the contraints, apply a regex to match the action values like: (foo|bar|biz|bang) and the same for the controller: (home|customer|products) for each controller. However, this has a problem in the fact that I may need to do this:

~/Foo/Home/123 // Should map to "DefaultwithPdn"

~/Foo/Home/abc // Should map to "DefaultWithClientId"

Which means that if the Foo Controller has an action that takes a pdn and another action that takes a clientId (which happens all the time in this app), the wrong route is chosen.

To hardcode these contstraints into each possible controller/action combo seems like a lot of duplication to me and I have the feeling I've been looking at the problem for too long so I need another pair of eyes to help out.

Can I have generic routes to handle this scenario? Or do I need to have custom routes for each controller with constraints applied to the actions on those routes?

Thanks

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

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

发布评论

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

评论(2

单挑你×的.吻 2024-10-16 17:45:50

通过删除 null 并将其替换为该路由所需的约束,向路由添加约束:

对于 PDN,对数字使用正则表达式:

   routes.MapRoute(
         "DefaultWithPdn",
         "{controller}/{action}/{pdn}",
         new { controller = "", action = "Index", pdn = "" },
         new { pdn = @"\d+" } 
     );

对于 ClientID,对所有字符使用正则表达式:

    routes.MapRoute(
       "DefaultWithClientId",
       "{controller}/{action}/{clientid}",
       new { controller = "", action = "index", clientid = "" },
       new { clientid = @"[A-Za-z]+" }
   );

因为 I不要把正则表达式的细节记在脑子里,我通常使用备忘单

Add constraints to your routes by removing the null and replacing it with the constraint needed for that route:

For PDN, use a regular expression for digits:

   routes.MapRoute(
         "DefaultWithPdn",
         "{controller}/{action}/{pdn}",
         new { controller = "", action = "Index", pdn = "" },
         new { pdn = @"\d+" } 
     );

For ClientID, use a regular expression for all characters:

    routes.MapRoute(
       "DefaultWithClientId",
       "{controller}/{action}/{clientid}",
       new { controller = "", action = "index", clientid = "" },
       new { clientid = @"[A-Za-z]+" }
   );

Since I don't keep the minutia of regular expression stuff in my head, I generally use a cheat sheet.

且行且努力 2024-10-16 17:45:50

您应该添加一些路由约束,表示 PDN 路由与数字匹配,而 ClientId 与字符串匹配。

我通常会创建一系列匹配项以在整个路由声明中使用,如下所示:

readonly static string ALPHA_MATCH = @"[\da-zA-Z]";
readonly static string DIGIT_MATCH = @"\d+";

然后将约束添加到路由,如下所示:

routes.MapRoute(
    "DefaultWithPdn",
    "{controller}/{action}/{pdn}",
    new { controller = "", action = "Index", pdn = "" },
    new { pdn = DIGIT_MATCH }
);

routes.MapRoute(
    "DefaultWithClientId",
    "{controller}/{action}/{clientId}",
    new { controller = "", action = "index", clientid = "" },
    new { clientId = ALPHA_MATCH }
);

You should add some route constraints that say the PDN route matches numbers and the ClientId matches strings

I usually create a series of matches to use throughout my route declaration like so:

readonly static string ALPHA_MATCH = @"[\da-zA-Z]";
readonly static string DIGIT_MATCH = @"\d+";

then add the constraints to the routes like this:

routes.MapRoute(
    "DefaultWithPdn",
    "{controller}/{action}/{pdn}",
    new { controller = "", action = "Index", pdn = "" },
    new { pdn = DIGIT_MATCH }
);

routes.MapRoute(
    "DefaultWithClientId",
    "{controller}/{action}/{clientId}",
    new { controller = "", action = "index", clientid = "" },
    new { clientId = ALPHA_MATCH }
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文