首页 > 解决方案 > MVC 路由 - 存在默认值时不应用查询字符串

问题描述

我正在使用这个路由配置:

   routes.MapRoute("Default23",
                "{category}",
                new { controller = "Product", action = "List", page = 1 }
            );

这是控制器方法:

 public ViewResult List(string category, int page = 1)
{
}

但是,如果我使用:

http://localhost:44123/chess?page=2

然后我看到page=1 (不是 2 ,正如我所料):

在此处输入图像描述

顺便说一句 - 如果我将路线更改为:

 routes.MapRoute("Default23",
                "{category}",
                new { controller = "Product", action = "List"  }
            );

然后我确实看到了正确的值:

在此处输入图像描述

为什么会这样?如果我不设置值,我只想设置一个默认值。为什么设置默认值会阻止读取查询字符串值?

标签: asp.net-mvcasp.net-mvc-routing

解决方案


为了解释这种行为,MapRoute的第三个参数是(我的重点)

包含默认路由值的对象。

通过指定new { controller = "Product", action = "List", page = 1 },您正在定义一个路由值page(即使它不是您的 url 定义中的一个段)并给它一个默认值1.

现在,当您导航到../chess?page=2它时,它与您的Default23路线匹配,并且“国际象棋”的值被分配给{category}段,但没有分配任何内容,page因为没有段{page}(它的查询字符串值)。

执行您的List(string category, int page = 1)方法时,DefaultModelBinder将按以下顺序评估绑定值

  1. 之前绑定的动作参数,当动作是子动作时
  2. 表单值
  3. JSON 请求正文(ajax 调用)
  4. 路线数据
  5. 查询字符串参数
  6. 发布的文件

对于 GET,1、2、3 和 6 不适用,因此第DefaultModelBinder一个评估 Route 数据 ( ) 并为(来自 url)RouteData.Values找到“chess”值。category它还找到一个值“1” page(因为您在路由定义中为它定义了一个默认值)。

此时你有category="chess", page=1.

然后DefaultModelBinder评估 Query 字符串参数 ( Request.QueryString) 并为 找到值“2” page,但由于page已经设置,因此将其忽略。默认情况下,DefaultModelBinder绑定它找到的第一个匹配项并忽略所有后续匹配项(除非绑定到IEnumerable属性)。

所以在这一点上(绑定过程结束)你仍然有category="chess", page=1.


推荐阅读