MVC маршрутизация - строки запроса не применяются, если присутствует значение по умолчанию - PullRequest
0 голосов
/ 10 ноября 2018

Я использую эту конфигурацию маршрута:

   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, как я ожидал):

enter image description here

BTw - если я изменю маршрут на:

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

Тогда я вижу правильное значение:

enter image description here

Почему это происходит? все, что я хотел, это установить значение по умолчанию, если я не установил значение , Почему установка значения по умолчанию запрещает чтение значения строки запроса?

1 Ответ

0 голосов
/ 11 ноября 2018

Чтобы объяснить поведение, 3-й аргумент MapRoute (мой акцент)

Объект, который содержит значения по умолчанию route values.

Указав new { controller = "Product", action = "List", page = 1 }, вы определяете значение маршрута для page (даже если оно не является сегментом в вашем определении URL) и присваиваете ему значение по умолчанию 1.

Теперь, когда вы переходите к ../chess?page=2, он соответствует вашему маршруту Default23, и значение 'chess' присваивается сегменту {category}, но ничего не назначается page, потому что для * нет сегмента 1022 * (это значение строки запроса).

Когда ваш метод List(string category, int page = 1) выполняется, DefaultModelBinder оценивает значения для привязки в следующем порядке

  1. Ранее связанные параметры действия, когда действие является дочерним Действие
  2. Значения формы
  3. Тело запроса JSON (ajax-вызовы)
  4. Данные маршрута
  5. Параметры строки запроса
  6. Прикрепленные файлы

Для GET 1, 2, 3 и 6 не применимы, поэтому DefaultModelBinder сначала оценивает данные маршрута (RouteData.Values) и находит значение "chess" для category (из URL) , Он также находит значение «1» для page (поскольку вы определили для него значение по умолчанию в определении маршрута).

На данный момент у вас есть category="chess", page=1.

Затем DefaultModelBinder оценивает строковые параметры запроса (Request.QueryString) и находит значение "2" для page, но, поскольку page уже установлено, его игнорируют. По умолчанию DefaultModelBinder связывает первое найденное совпадение и игнорирует все последующие совпадения (если не привязано к свойству IEnumerable).

Итак, на данный момент (конец процесса привязки) у вас все еще есть category="chess", page=1.

...