可以设置带有 null {id} 的 {id}/{controller}/{action} 路由吗?

发布于 2024-12-18 11:03:42 字数 839 浏览 1 评论 0原文

我有一个网站,出于业务原因,需要有一个非标准路由设置,而

{id}/{controller}/{action}.

不是 http://site/Controller/Id,我需要它路由到 http://站点/Id/控制器。这在 99% 的情况下都可以正常工作,但如果没有提供 Id,则将使用假定值(我们称之为“0”)。

我设法通过指定默认值来获取 Home 控制器,但让我丧命的是试图让 http://site/MyController 发挥作用,就好像它真的是 http://site/0 一样/MyController。我尝试的每个组合似乎都试图在没有实际 {id} 的情况下使用“MyController”来评估 {id}

这是我目前的注册路线:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

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

I have a site that, for business reasons, needs to have a nonstandard routing setup following

{id}/{controller}/{action}.

Instead of http://site/Controller/Id, I need it to route to http://site/Id/Controller. This works fine in 99% of cases, but if no Id is provided an assumed value (let's just call it "0") will be used.

I managed to get the Home controller by specifying defaults, but what's killing me is trying to get http://site/MyController to function as if it were really http://site/0/MyController. Every combination I try seems to try to evaluate {id} with "MyController" in absense of an actual {id}.

This is my RegisterRoutes currently:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

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

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

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

发布评论

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

评论(1

可选路段只能放置在路线末端,或者更好地放置在必需路段之后。这就是为什么您必须添加一个不带 id 段的附加路由定义,并将其默认值定义为 0

id 是数字

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

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

    routes.MapRoute(
        "DefaultId",
        "{controller}/{action}",
        new { controller = "Home", action = "Index", id = "0" }
    );
}

如您所见,第一个路由定义还包含对 id 段的约束,这要求它必须是数字。这就是窍门。

id 是字母数字,但与任何控制器名称不匹配

如果 id 不是数字,但可以是字母数字,那么您将不得不采取不同的方法...

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

    routes.MapRoute(
        "DefaultId",
        "{controller}/{action}",
        new { controller = "Home", action = "Index", id = "0" },
        new { controller = @"Home|Admin|Categories|Items" }
    );

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

那么您将拥有对控制器段施加约束,因为它们的数量是有限的。请注意,路由定义已交换,因此无 id 的路由现在是第一个,而带有 id 的路由现在是第二个。只要 id 永远不能与控制器名称具有相同的值,这应该有效。

id 可以是任何东西

但是如果 id 的值可以等于控制器名称怎么办?在这种情况下,您将必须更严格地定义路由规则,因为您很可能必须省略默认值并根据段数提供更多路由:零、一、二、三甚至更多(如果需要)。

Optional segments can only be placed at the end of your route or better after required ones. That's why you have to add an additional route definition without id segment that also defines its default as 0.

id is numeric

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

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

    routes.MapRoute(
        "DefaultId",
        "{controller}/{action}",
        new { controller = "Home", action = "Index", id = "0" }
    );
}

As you can see, the first route definition also includes a constraint for the id segment which makes a requirement for it to be numeric. That's the trick.

id is alphanumeric but not matching any controller name

In case id is not numeric but can be alpha numeric then you will have to take a different approach...

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

    routes.MapRoute(
        "DefaultId",
        "{controller}/{action}",
        new { controller = "Home", action = "Index", id = "0" },
        new { controller = @"Home|Admin|Categories|Items" }
    );

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

Then you will have to put a constraint on the controller segment, because you have a finite number of them. Mind that route definitions have swapped so the id-less one is now the first and the one with the id is now second. This should work as long as id can never have the same value as controller name.

id can be anything really

But what if id can have a value equal to a controller name? Well in that case you will have to define your routing rules a bit more strictly because you will most likely have to omit default values and provide more routes based on number of segments: zero, one, two, three or even more if required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文