ASP中的约束.. NET MVC路由问题

本文关键字:MVC 路由 问题 NET 约束 ASP | 更新日期: 2023-09-27 18:02:01

我试着从这个网站创建一个例子。

他们定义了这样一个路由:

routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"'d+" }
);

表示当productId没有整数值时,会出现The resource could not be found错误。(我访问了http://website.com/product/1a,然后显示错误,否则将显示视图)

但是如果我把route的url格式改成这样:

"Product/{action}/{productId}"

并像:http://website.com/Product/Details/1a那样访问它,然后出现如下错误:The parameters dictionary contains a null entry for parameter 'productId' of non-nullable type 'System.Int32' for method

那么,为什么不显示The resource could not be found错误呢?为什么当我把约束到路由时达到了动作?

PS:我更改了route的url格式,现在它看起来像:
routes.MapRoute(
    "Product",
    "Product/{action}/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"'d+" }
);

ASP中的约束.. NET MVC路由问题

原因不是你指定的路由,而是代码中的另一个路由项,很可能是默认的MVC路由:

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

productId的值与约束不匹配时,路由引擎继续检查下一个映射。然后它匹配最后一个,但是当尝试调用您的方法时,模型绑定器无法将字符串1a转换为int,这实际上意味着缺少productId参数。

为什么The resource could not be found错误

routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"'d+" }
);

当url为http://website.com/product/1a

答案:你得到的错误,因为当你在url的路由上应用约束,如果约束不匹配MVC只是拒绝那个请求。这是唯一的原因,你得到错误的资源未找到


为什么The parameters dictionary contains a null entry for parameter 'productId' of non-nullable type 'System.Int32' for method错误

routes.MapRoute(
    "Product",
    "Product/{action}/{productId}",
    new {controller="Product", action="Details"}
);

当url http://website.com/Product/Details/1a

回答:在这种情况下,没有routconstraint被应用,所以ModelBinder尝试使用DefaultValuProvider匹配参数,如果它无法匹配参数的值,那么它会抛出错误,因为你在这里没有转换意味着null。

要避免此错误,您可以尝试执行

。将默认值传递给操作方法

  public ActionResult Index(int id=0)

b。创建带有可空参数的方法,以便自动处理空

  public ActionResult Index(int? id)

问题不是因为约束路由

routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"'d+" }
);

根据上面的代码,你正在寻找产品id,这是整数,所以如果你提供像http://website.com/Product/Details/1a这样的字符串,它会尝试匹配第一个值与第一个页面持有人意味着在这种情况下产品与productId匹配后的任何东西…当模块绑定器发现它的string而不是int时,使用ModuleBinder,即不能在int中转换string,它会抛出错误,你正在得到。

因此,根据您的路由,它匹配Details与产品id,但无法找到1a的匹配,这就是您获得未找到资源的原因。


当你有这样的路由Product/{action}/{productId}调用这样的url http://website.com/Product/Details/1a它匹配Details{action} 1a{ProductId}然后你得到错误The parameters dictionary contains a null entry for parameter 'productId' of non-nullable type 'System.Int32' for method