在 MVC3 中生成 RouteUrl 在一种情况下返回 null

发布于 2024-11-30 14:57:01 字数 918 浏览 0 评论 0原文

我有一个这样定义的路线:

 routes.MapRoute("Date", "Date/{year}/{month}/{day}", 
    new { controller = "Date", action = "Index", year = UrlParameter.Optional,
         month = UrlParameter.Optional, day = UrlParameter.Optional });

所以它有 3 个可选参数,年、月和日。它在路由 GET 请求时工作正常,以下所有工作都工作正常:

http://myhost/myapp/Date
http://myhost/myapp/Date/2011
http://myhost/myapp/Date/2011/8
http://myhost/myapp/Date/2011/8/17

使用 RouteUrl 生成链接在除一种情况外的所有情况下都有效。

例如,我想要一个包含年份和月份的链接的情况下效果很好。在我看来,我使用以下(简化的)代码:

 string linkUrl = Url.RouteUrl("Date",
     new { controller = "Date", year = 2011, month = 8 },
     Request.Url.Scheme);

但是仅定义年份的情况不起作用并返回 null,代码是:

string linkUrl = Url.RouteUrl("Date",
    new { controller = "Date", year = 2011 },
    Request.Url.Scheme);

所以这对我来说看起来都是正确的。任何线索我做错了什么,或者如何进一步调试。

I have a route defined like this:

 routes.MapRoute("Date", "Date/{year}/{month}/{day}", 
    new { controller = "Date", action = "Index", year = UrlParameter.Optional,
         month = UrlParameter.Optional, day = UrlParameter.Optional });

So it has 3 optional parameters, year, month and day. It works fine in routing a GET request, all the following work fine:

http://myhost/myapp/Date
http://myhost/myapp/Date/2011
http://myhost/myapp/Date/2011/8
http://myhost/myapp/Date/2011/8/17

Generating links using RouteUrl works in all cases except one.

For example, the case where I want a link including the year and a month works fine. I use the following (simplified) code in my view:

 string linkUrl = Url.RouteUrl("Date",
     new { controller = "Date", year = 2011, month = 8 },
     Request.Url.Scheme);

But the case where only the year is defined does not work and returns null, the code is:

string linkUrl = Url.RouteUrl("Date",
    new { controller = "Date", year = 2011 },
    Request.Url.Scheme);

So it all looks correct to me. Any clue what I'm doing wrong, or how to debug this further.

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

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

发布评论

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

评论(1

執念 2024-12-07 14:57:01

好吧,看起来这是 MVC3 中引入的一个已知“问题”,但由于 .NET4 中路由的潜在问题,因此 MVC 团队无法快速修复。虽然默默地返回 null 显然是一个错误,但不清楚我最初创建的路由是否也应该按照我想要的方式工作(见下文)。

我发现这个 SO Question 要求人们用两个可选参数复制类似的问题,答案参考 本文也有一个解决方法。

我按照解决方法解决了这个问题,方法是创建多个路由,每个路由中只有一个可选参数。

  routes.MapRoute(
    "Date-ByDay", // Route name
    "Date/{year}/{month}/{day}", // URL with parameters
    new { controller = "Date", action = "Index" } // Parameter defaults
  );

  routes.MapRoute(
    "Date-ByMonth", // Route name
    "Date/{year}/{month}", // URL with parameters
    new { controller = "Date", action = "Index", month = UrlParameter.Optional } // Parameter defaults
  );

  routes.MapRoute(
    "Date-ByYear", // Route name
    "Date/{year}", // URL with parameters
    new { controller = "Date", action = "Index", year = UrlParameter.Optional } // Parameter defaults
  );

我原来的方法是否应该起作用是有争议的,例如,如果您错过了可选的“月份”参数怎么办,并且原始路由是否应该生成 /2011/18 的 URL? “解决方法”虽然丑陋,但对于您想要的行为肯定更加明确。我认为,我的原始路线的预期行为(对我来说)很清楚,并且如果我要求一条包含一年和一天的路线,而错过了月份,我会预料到会有例外- 但我可以看到这可能不是每个人的观点。然而,这在 MVC2 中确实有效。

Ok, it looks like this is a known 'issue' introduced in MVC3, but due to an underlying issue in routing in .NET4, so cannot be quickly fixed by the MVC team. Although silently returning null is clearly a bug, its unclear whether the route I originally created should be allowed to work the way I wanted it too (see below).

I found this SO Question which asks for people to replicate a similar issue with two optional parameters, and an answer refers to this article too, which has a workaround.

I resolved this as per the workaround by making multiple routes, with only one optional parameter in each.

  routes.MapRoute(
    "Date-ByDay", // Route name
    "Date/{year}/{month}/{day}", // URL with parameters
    new { controller = "Date", action = "Index" } // Parameter defaults
  );

  routes.MapRoute(
    "Date-ByMonth", // Route name
    "Date/{year}/{month}", // URL with parameters
    new { controller = "Date", action = "Index", month = UrlParameter.Optional } // Parameter defaults
  );

  routes.MapRoute(
    "Date-ByYear", // Route name
    "Date/{year}", // URL with parameters
    new { controller = "Date", action = "Index", year = UrlParameter.Optional } // Parameter defaults
  );

It is arguable whether my original approach should work anyway, for example what if you miss out the optional 'month' parameter, and should the original route generate a URL of /2011/18? The 'workaround' whilst ugly, certainly is much more explicit about the behavior you want. I would argue that the expected behavior of my original route is clear (to me) and that I would have expected an exception if I had asked for a route with a year and a day, missing out the month - but I can see that this may not be everyones point of view. However this did work in MVC2.

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