MVC routing - Query strings are not applied when default is present









up vote
1
down vote

favorite












I'm using this route config :



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


Here is the controller method :



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




However , if I use :



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


Then I see that page=1 ( not 2 , as I expected):



enter image description here



BTw - if I change the route to :



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


Then I do see the right value:



enter image description here



Why is it happening ? all I wanted is to set a default value if I don't set a value
.
Why does setting a default value , prevents reading the query string value ?










share|improve this question

















  • 1




    Possible duplicate of How do I route a URL with a querystring in ASP.NET MVC?
    – Hooman
    Nov 10 at 23:52










  • @Hooman, That is not what OP is asking - you might consider retracting the close vote
    – Stephen Muecke
    Nov 11 at 2:21










  • @StephenMuecke, thanks... I thought this answer explains the problem...
    – Hooman
    Nov 11 at 2:28














up vote
1
down vote

favorite












I'm using this route config :



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


Here is the controller method :



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




However , if I use :



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


Then I see that page=1 ( not 2 , as I expected):



enter image description here



BTw - if I change the route to :



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


Then I do see the right value:



enter image description here



Why is it happening ? all I wanted is to set a default value if I don't set a value
.
Why does setting a default value , prevents reading the query string value ?










share|improve this question

















  • 1




    Possible duplicate of How do I route a URL with a querystring in ASP.NET MVC?
    – Hooman
    Nov 10 at 23:52










  • @Hooman, That is not what OP is asking - you might consider retracting the close vote
    – Stephen Muecke
    Nov 11 at 2:21










  • @StephenMuecke, thanks... I thought this answer explains the problem...
    – Hooman
    Nov 11 at 2:28












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I'm using this route config :



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


Here is the controller method :



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




However , if I use :



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


Then I see that page=1 ( not 2 , as I expected):



enter image description here



BTw - if I change the route to :



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


Then I do see the right value:



enter image description here



Why is it happening ? all I wanted is to set a default value if I don't set a value
.
Why does setting a default value , prevents reading the query string value ?










share|improve this question













I'm using this route config :



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


Here is the controller method :



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




However , if I use :



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


Then I see that page=1 ( not 2 , as I expected):



enter image description here



BTw - if I change the route to :



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


Then I do see the right value:



enter image description here



Why is it happening ? all I wanted is to set a default value if I don't set a value
.
Why does setting a default value , prevents reading the query string value ?







asp.net-mvc asp.net-mvc-routing






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 20:48









d11

1038




1038







  • 1




    Possible duplicate of How do I route a URL with a querystring in ASP.NET MVC?
    – Hooman
    Nov 10 at 23:52










  • @Hooman, That is not what OP is asking - you might consider retracting the close vote
    – Stephen Muecke
    Nov 11 at 2:21










  • @StephenMuecke, thanks... I thought this answer explains the problem...
    – Hooman
    Nov 11 at 2:28












  • 1




    Possible duplicate of How do I route a URL with a querystring in ASP.NET MVC?
    – Hooman
    Nov 10 at 23:52










  • @Hooman, That is not what OP is asking - you might consider retracting the close vote
    – Stephen Muecke
    Nov 11 at 2:21










  • @StephenMuecke, thanks... I thought this answer explains the problem...
    – Hooman
    Nov 11 at 2:28







1




1




Possible duplicate of How do I route a URL with a querystring in ASP.NET MVC?
– Hooman
Nov 10 at 23:52




Possible duplicate of How do I route a URL with a querystring in ASP.NET MVC?
– Hooman
Nov 10 at 23:52












@Hooman, That is not what OP is asking - you might consider retracting the close vote
– Stephen Muecke
Nov 11 at 2:21




@Hooman, That is not what OP is asking - you might consider retracting the close vote
– Stephen Muecke
Nov 11 at 2:21












@StephenMuecke, thanks... I thought this answer explains the problem...
– Hooman
Nov 11 at 2:28




@StephenMuecke, thanks... I thought this answer explains the problem...
– Hooman
Nov 11 at 2:28












1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










To explain the behavior, the 3rd argument of MapRoute is (my emphasis)




An object that contains default route values.




By specifying new controller = "Product", action = "List", page = 1 you are defining a route value for page (even though its not a segment in your url definition) and giving it a default value of 1.



Now when you navigate to ../chess?page=2 it matches your Default23 route, and the value of 'chess' is assigned to the category segment, but nothing is assigned to page because there is no segment for page (its a query string value).



When your List(string category, int page = 1) method is executed, the DefaultModelBinder evaluates values for binding in the following order



  1. Previously bound action parameters, when the action is a child
    action

  2. Form values

  3. JSON Request body (ajax calls)

  4. Route data

  5. Query string parameters

  6. Posted files

For a GET, 1, 2, 3 and 6 are not applicable, so the DefaultModelBinder first evaluates the Route data (RouteData.Values) and finds a value of "chess" for category (from the url). It also finds a value of "1" for page (because you defined a default value for it in the route definition).



At this point you have category="chess", page=1.



The DefaultModelBinder then evaluates the Query string parameters (Request.QueryString) and finds a value of "2" for page, but because page already has been set, its ignored. By default, the DefaultModelBinder binds the first match it finds and ignores all subsequent matches (unless binding to an IEnumerable property).



So at this point (the end of the binding process) you still have category="chess", page=1.






share|improve this answer




















  • So what if I want specify it conditionally via QS and still have a default value ?
    – d11
    Nov 11 at 6:59











  • You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
    – Stephen Muecke
    Nov 11 at 7:27










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243258%2fmvc-routing-query-strings-are-not-applied-when-default-is-present%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










To explain the behavior, the 3rd argument of MapRoute is (my emphasis)




An object that contains default route values.




By specifying new controller = "Product", action = "List", page = 1 you are defining a route value for page (even though its not a segment in your url definition) and giving it a default value of 1.



Now when you navigate to ../chess?page=2 it matches your Default23 route, and the value of 'chess' is assigned to the category segment, but nothing is assigned to page because there is no segment for page (its a query string value).



When your List(string category, int page = 1) method is executed, the DefaultModelBinder evaluates values for binding in the following order



  1. Previously bound action parameters, when the action is a child
    action

  2. Form values

  3. JSON Request body (ajax calls)

  4. Route data

  5. Query string parameters

  6. Posted files

For a GET, 1, 2, 3 and 6 are not applicable, so the DefaultModelBinder first evaluates the Route data (RouteData.Values) and finds a value of "chess" for category (from the url). It also finds a value of "1" for page (because you defined a default value for it in the route definition).



At this point you have category="chess", page=1.



The DefaultModelBinder then evaluates the Query string parameters (Request.QueryString) and finds a value of "2" for page, but because page already has been set, its ignored. By default, the DefaultModelBinder binds the first match it finds and ignores all subsequent matches (unless binding to an IEnumerable property).



So at this point (the end of the binding process) you still have category="chess", page=1.






share|improve this answer




















  • So what if I want specify it conditionally via QS and still have a default value ?
    – d11
    Nov 11 at 6:59











  • You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
    – Stephen Muecke
    Nov 11 at 7:27














up vote
2
down vote



accepted










To explain the behavior, the 3rd argument of MapRoute is (my emphasis)




An object that contains default route values.




By specifying new controller = "Product", action = "List", page = 1 you are defining a route value for page (even though its not a segment in your url definition) and giving it a default value of 1.



Now when you navigate to ../chess?page=2 it matches your Default23 route, and the value of 'chess' is assigned to the category segment, but nothing is assigned to page because there is no segment for page (its a query string value).



When your List(string category, int page = 1) method is executed, the DefaultModelBinder evaluates values for binding in the following order



  1. Previously bound action parameters, when the action is a child
    action

  2. Form values

  3. JSON Request body (ajax calls)

  4. Route data

  5. Query string parameters

  6. Posted files

For a GET, 1, 2, 3 and 6 are not applicable, so the DefaultModelBinder first evaluates the Route data (RouteData.Values) and finds a value of "chess" for category (from the url). It also finds a value of "1" for page (because you defined a default value for it in the route definition).



At this point you have category="chess", page=1.



The DefaultModelBinder then evaluates the Query string parameters (Request.QueryString) and finds a value of "2" for page, but because page already has been set, its ignored. By default, the DefaultModelBinder binds the first match it finds and ignores all subsequent matches (unless binding to an IEnumerable property).



So at this point (the end of the binding process) you still have category="chess", page=1.






share|improve this answer




















  • So what if I want specify it conditionally via QS and still have a default value ?
    – d11
    Nov 11 at 6:59











  • You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
    – Stephen Muecke
    Nov 11 at 7:27












up vote
2
down vote



accepted







up vote
2
down vote



accepted






To explain the behavior, the 3rd argument of MapRoute is (my emphasis)




An object that contains default route values.




By specifying new controller = "Product", action = "List", page = 1 you are defining a route value for page (even though its not a segment in your url definition) and giving it a default value of 1.



Now when you navigate to ../chess?page=2 it matches your Default23 route, and the value of 'chess' is assigned to the category segment, but nothing is assigned to page because there is no segment for page (its a query string value).



When your List(string category, int page = 1) method is executed, the DefaultModelBinder evaluates values for binding in the following order



  1. Previously bound action parameters, when the action is a child
    action

  2. Form values

  3. JSON Request body (ajax calls)

  4. Route data

  5. Query string parameters

  6. Posted files

For a GET, 1, 2, 3 and 6 are not applicable, so the DefaultModelBinder first evaluates the Route data (RouteData.Values) and finds a value of "chess" for category (from the url). It also finds a value of "1" for page (because you defined a default value for it in the route definition).



At this point you have category="chess", page=1.



The DefaultModelBinder then evaluates the Query string parameters (Request.QueryString) and finds a value of "2" for page, but because page already has been set, its ignored. By default, the DefaultModelBinder binds the first match it finds and ignores all subsequent matches (unless binding to an IEnumerable property).



So at this point (the end of the binding process) you still have category="chess", page=1.






share|improve this answer












To explain the behavior, the 3rd argument of MapRoute is (my emphasis)




An object that contains default route values.




By specifying new controller = "Product", action = "List", page = 1 you are defining a route value for page (even though its not a segment in your url definition) and giving it a default value of 1.



Now when you navigate to ../chess?page=2 it matches your Default23 route, and the value of 'chess' is assigned to the category segment, but nothing is assigned to page because there is no segment for page (its a query string value).



When your List(string category, int page = 1) method is executed, the DefaultModelBinder evaluates values for binding in the following order



  1. Previously bound action parameters, when the action is a child
    action

  2. Form values

  3. JSON Request body (ajax calls)

  4. Route data

  5. Query string parameters

  6. Posted files

For a GET, 1, 2, 3 and 6 are not applicable, so the DefaultModelBinder first evaluates the Route data (RouteData.Values) and finds a value of "chess" for category (from the url). It also finds a value of "1" for page (because you defined a default value for it in the route definition).



At this point you have category="chess", page=1.



The DefaultModelBinder then evaluates the Query string parameters (Request.QueryString) and finds a value of "2" for page, but because page already has been set, its ignored. By default, the DefaultModelBinder binds the first match it finds and ignores all subsequent matches (unless binding to an IEnumerable property).



So at this point (the end of the binding process) you still have category="chess", page=1.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 11 at 2:15









Stephen Muecke

97.7k1995119




97.7k1995119











  • So what if I want specify it conditionally via QS and still have a default value ?
    – d11
    Nov 11 at 6:59











  • You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
    – Stephen Muecke
    Nov 11 at 7:27
















  • So what if I want specify it conditionally via QS and still have a default value ?
    – d11
    Nov 11 at 6:59











  • You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
    – Stephen Muecke
    Nov 11 at 7:27















So what if I want specify it conditionally via QS and still have a default value ?
– d11
Nov 11 at 6:59





So what if I want specify it conditionally via QS and still have a default value ?
– d11
Nov 11 at 6:59













You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
– Stephen Muecke
Nov 11 at 7:27




You have already defined a default in the List() method (i.e. int page = 1) so if you omit page = 1 from the route definition navigate to .../chess, (i.e. no query string) then the value of page will be page=1
– Stephen Muecke
Nov 11 at 7:27

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243258%2fmvc-routing-query-strings-are-not-applied-when-default-is-present%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Top Tejano songwriter Luis Silva dead of heart attack at 64

ReactJS Fetched API data displays live - need Data displayed static

政党