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

时间:2015-07-09 08:44:30

标签: c# asp.net-mvc-4

我尝试从this website创建一个示例。

他们定义了一条路线:

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然后显示错误,否则将显示视图)

但是如果我将url格式从route更改为:

"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:我改变了路由的url格式,现在看起来像:

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

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

为何

错误The resource could not be found
routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"\d+" }
);

当网址为http://website.com/product/1a

答案:您收到错误是因为当您对网址路由应用约束时,如果约束不匹配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"}
);

当网址为http://website.com/Product/Details/1a

答案:在这种情况下,没有应用任何routconstrain,因此ModelBinder尝试使用DefaultValuProvider匹配参数如果它无法将值与参数匹配,那么当它到达此处时因为没有转换方式而引发错误空。

为避免此错误,您可以尝试此

一个。将defualt值传递给行动方法

  public ActionResult Index(int id=0)

湾使用可为空的参数创建方法,以便null自动处理

  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匹配后的任何内容。 。匹配此mvc使用ModuleBinder当模块绑定器找到其string而非int,即无法在string中转换int时,它会引发错误。

因此,根据您的路线,它会将Details与产品ID匹配,但无法找到1a的匹配项,这是您找不到资源的原因。 < / p>

如果您拥有此Product/{action}/{productId}之类的路线,并且像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