MVC 路由 - 存在默认值时不应用查询字符串
MVC routing - Query strings are not applied when default is present
我正在使用这个路由配置:
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):
BTw - 如果我将路线更改为:
routes.MapRoute("Default23",
"{category}",
new { controller = "Product", action = "List" }
);
然后我确实看到了正确的值:
为什么会这样?如果我不设置值,我只想设置一个默认值
.
为什么设置默认值会阻止读取查询字符串值?
为了解释这种行为,MapRoute 的第三个参数是(我强调的)
An object that contains default route values.
通过指定 new { controller = "Product", action = "List", page = 1 }
,您正在为 page
定义一个路由值(即使它不是您 url 定义中的一个段)并给它一个默认值 1
.
现在,当您导航到 ../chess?page=2
时,它与您的 Default23
路线匹配,并且 'chess' 的值已分配给 {category}
段,但没有分配任何内容page
因为 {page}
没有段(它是一个查询字符串值)。
当执行您的 List(string category, int page = 1)
方法时,DefaultModelBinder
按以下顺序计算绑定值
- 之前绑定的动作参数,当动作是子动作时
动作
- 表单值
- JSON 请求正文(ajax 调用)
- 路由数据
- 查询字符串参数
- 已发布的文件
对于GET,1、2、3、6不适用,所以DefaultModelBinder
先求Route数据(RouteData.Values
),找到"chess"的值category
(来自url)。它还为 page
找到值“1”(因为您在路由定义中为其定义了默认值)。
此时你有 category="chess", page=1
.
然后 DefaultModelBinder
计算查询字符串参数 (Request.QueryString
) 并找到 page
的值“2”,但是因为 page
已经设置, 它被忽略了。默认情况下,DefaultModelBinder
绑定它找到的第一个匹配项并忽略所有后续匹配项(除非绑定到 IEnumerable
属性)。
所以此时(绑定过程结束)您仍然有 category="chess", page=1
。
我正在使用这个路由配置:
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):
BTw - 如果我将路线更改为:
routes.MapRoute("Default23",
"{category}",
new { controller = "Product", action = "List" }
);
然后我确实看到了正确的值:
为什么会这样?如果我不设置值,我只想设置一个默认值 . 为什么设置默认值会阻止读取查询字符串值?
为了解释这种行为,MapRoute 的第三个参数是(我强调的)
An object that contains default route values.
通过指定 new { controller = "Product", action = "List", page = 1 }
,您正在为 page
定义一个路由值(即使它不是您 url 定义中的一个段)并给它一个默认值 1
.
现在,当您导航到 ../chess?page=2
时,它与您的 Default23
路线匹配,并且 'chess' 的值已分配给 {category}
段,但没有分配任何内容page
因为 {page}
没有段(它是一个查询字符串值)。
当执行您的 List(string category, int page = 1)
方法时,DefaultModelBinder
按以下顺序计算绑定值
- 之前绑定的动作参数,当动作是子动作时 动作
- 表单值
- JSON 请求正文(ajax 调用)
- 路由数据
- 查询字符串参数
- 已发布的文件
对于GET,1、2、3、6不适用,所以DefaultModelBinder
先求Route数据(RouteData.Values
),找到"chess"的值category
(来自url)。它还为 page
找到值“1”(因为您在路由定义中为其定义了默认值)。
此时你有 category="chess", page=1
.
然后 DefaultModelBinder
计算查询字符串参数 (Request.QueryString
) 并找到 page
的值“2”,但是因为 page
已经设置, 它被忽略了。默认情况下,DefaultModelBinder
绑定它找到的第一个匹配项并忽略所有后续匹配项(除非绑定到 IEnumerable
属性)。
所以此时(绑定过程结束)您仍然有 category="chess", page=1
。