【问题标题】:MVC routing - Query strings are not applied when default is presentMVC 路由 - 存在默认值时不应用查询字符串
【发布时间】:2018-11-11 10:15:06
【问题描述】:

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

   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-mvc asp.net-mvc-routing


【解决方案1】:

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

一个包含默认 路由 值的对象。

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

现在,当您导航到 ../chess?page=2 时,它与您的 Default23 路线匹配,并且“棋”的值分配给 {category} 段,但没有分配给 page,因为没有 @ 段987654329@(它是一个查询字符串值)。

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

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

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

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

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

所以此时(绑定过程结束)您仍然拥有category="chess", page=1

【讨论】:

  • 如果我想通过 QS 有条件地指定它并且仍然有默认值怎么办?
  • 您已经在List() 方法中定义了一个默认值(即int page = 1),因此如果您从路由定义中省略page = 1,请导航到.../chess,(即没有查询字符串)然后page 的值将是 page=1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 2012-04-01
  • 1970-01-01
  • 2014-02-09
相关资源
最近更新 更多