【问题标题】:MVC Alternative routing is failing with optional parameterMVC 替代路由因可选参数而失败
【发布时间】:2014-12-02 13:43:30
【问题描述】:

我正在尝试在我的 MVC 5 网络应用中实现替代路由。

我有控制器代码:

namespace MyMvcProject.Web.Controllers
{
    [RoutePrefix("account")]
    public class AccountController : Controller {


        [Route("{param}")]
        [Authorize]
        public ActionResult Index(string param = null) {

...

在点击 url 时效果很好:http://example.com/account/testparam。 但是,我希望能够将值 param 作为可选参数。

我尝试将[Route("{param}")] 更改为[Route("{param}*")],但之后从未输入Index() 方法。我也尝试将其更改为 [Route("{param:string=Test}")],但使用术语 string 时出现路由运行时错误。

我的RoutConfig.cs 包含:

 public static void RegisterRoutes(RouteCollection routes) 
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapMvcAttributeRoutes();

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{param}",
                defaults: new { controller = "Home", action = "Index", param = UrlParameter.Optional }
            );
        }

有谁知道我如何强制Index() 使用这种替代路由语法具有可选参数?它在我的应用程序的其他部分非常有用,所以我想保留 RoutePrefixRoute 装饰器。

更新

我仍在尝试解决这个问题,因此我将路由装饰器更改为[Route("{param:int=0}")],将构造函数更改为public ActionResult Index(int id),它按预期工作(即http://example.com/account 的行为就像输入了http://example.com/account/0。这正是我想要的,只使用string 数据类型。

当我将装饰器更改为:[Route("{id:string=\"\"}")] 并将构造器更改为 public ActionResult Index(string id) 时,我看到运行时错误:

“DefaultInlineConstraintResolver”类型的内联约束解析器无法解析以下内联约束:“字符串”。

【问题讨论】:

    标签: c# model-view-controller routing


    【解决方案1】:

    @Brett 的 答案非常棒:将 ? 添加到 Route 属性中的参数,然后在 Action 签名中提供默认值允许该参数是可选的。

    这是 Mike Wasson 在Attribute Routing in Web API 2 上发表的一篇精彩文章,其中包括一篇关于可选参数的文章。

    Mike 还谈到了应用多个约束,并说:

    您可以对一个参数应用多个约束,以冒号分隔。

      [Route("users/{id:int:min(1)}")]
      public User GetUserById(int id) { ... }
    

    这也很有效...直到您想要多个约束一个可选参数。

    我们知道,应用? 允许参数是可选的。因此,以上面的例子为例,人们可能会认为

    [Route("users/{id:int?:min(1)}")]
    public User GetUserById(int id = 1) { ... }
    

    id 参数限制为大于0 的整数或为空(在这种情况下使用默认值1)。实际上,我们会收到错误消息:

    “DefaultInlineConstraintResolver”类型的内联约束解析器无法解析以下内联约束:“int?”。

    事实证明,约束的顺序很重要!只需将可选约束 ? 置于所有其他约束之后即可给出预期的行为

    [Route("users/{id:min(1):int?}")]
    public User GetUserById(int id = 1) { ... }
    

    这也适用于超过 2 个约束,例如

    [Route("users/{id:min(1):max(10):int?}")]
    public User GetUserById(int id = 1) { ... }
    

    【讨论】:

    • 关于订单的有用提示。
    【解决方案2】:

    找到答案here。我需要使用? 使param 可以为空。

    [Route("{param?}")]
    [Authorize]
    public ActionResult Index(string param = null) {
       ...
    }
    

    希望这对将来的某人有所帮助。 我找不到关于该主题的很多参考资料。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 2014-03-19
      • 2017-10-31
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多