ASP.Net MVC - обработка неверных параметров URL
Какой лучший способ обработать посетителя, создав свой собственный URL-адрес, и заменив то, что мы ожидаем от ID, что угодно?
Например:
ASP.Net MVC - обработка неверных параметров URL
Но пользователь может так же легко заменить URL-адрес:
https://stackoverflow.com/info/foo
Я подумал о том, чтобы сделать каждый параметр функции контроллера a String
и использовать Integer.TryParse()
для них - если это пройдет, то у меня есть идентификатор и вы можете продолжить, в противном случае я могу перенаправить пользователя в Unknown/not- найденный или индексный вид.
Qaru отлично справляется с этим, и я тоже хотел бы - как вы это делаете, или что бы вы предложили?
Ответы
Ответ 1
Вот пример маршрута, подобного вашему, с ограничением на число:
routes.MapRoute(
"Question",
"questions/{questionID}",
new { controller = "StackOverflow", action = "Question" },
new { questionID = @"\d+" } //Regex constraint specifying that it must be a number.
);
Здесь мы устанавливаем для параметра questionID как минимум одно число. Это также блокирует любые URL-адреса, содержащие что-либо, кроме целого числа, а также предотвращает необходимость в nullable int.
Примечание. Это не учитывает числа, которые больше, чем диапазон Int32 (-2147483647 - +2147483647). Я оставляю это как упражнение для решения пользователем.:)
Если пользователь вводит URL-адрес "questions/foo", они не будут воздействовать на действие "Вопрос" и проваливаться через него, потому что это не позволяет ограничить параметр. Если вы захотите: вы можете обрабатывать его дальше по маршруту catchall/default:
routes.MapRoute(
"Catchall",
"{*catchall}", // This is a wildcard routes
new { controller = "Home", action = "Lost" }
);
Это приведет к потере пользователя в действие "Потеря" на домашнем контроллере. Более подробную информацию о шаблоне можно найти здесь.
NB: Catchall должен находиться в качестве маршрута LAST. Размещение его дальше по цепочке означает, что это будет обрабатывать все остальные ниже, учитывая ленивый характер маршрутов в ASP.NET MVC.
Ответ 2
Вот некоторая полезная информация, которая может помочь.
Если у вас есть метод действий
public ActionResult Edit(int? id)
{}
тогда, если кто-то набирает
/Home/Edit/23
идентификатор параметра будет равен 23.
однако, если кто-то набирает
/Home/Edit/Junk
тогда id будет null, что довольно круто. Я думал, что это бросит ошибку приращения или что-то в этом роде. Это означает, что если id не является нулевым значением, то это действительное целое число и может быть передано вашим службам и т.д. Для взаимодействия db.
Надеюсь, это предоставит вам некоторую информацию, которую я нашел во время тестирования.
Ответ 3
В ASP.NET MVC вы можете определить фильтр, реализующий интерфейс IActionFilter. Вы сможете украсить свое действие этим атрибутом, чтобы он выполнялся до или после вашего действия.
В вашем случае вы определите его для выполнения "до" вашего действия. Таким образом, вы сможете отменить его, если есть ошибка в переданных параметрах. Ключевым преимуществом здесь является то, что вы только пишете код, который проверяет пройденные параметры один раз (т.е. Определяете его в своем фильтре) и используете его везде, где хотите, в действиях вашего контроллера.
Подробнее о фильтрах MVC здесь: http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx
Ответ 4
Вы можете указать ограничения как регулярные выражения или определить пользовательские ограничения. Взгляните на это сообщение в блоге для получения дополнительной информации:
http://weblogs.asp.net/stephenwalther/archive/2008/08/06/asp-net-mvc-tip-30-create-custom-route-constraints.aspx
Вам все равно придется иметь дело с ситуацией, когда id 43243 не сопоставляется ни с чем, что можно было бы рассматривать как IActionFilter или непосредственно в вашем контроллере.
Ответ 5
Проблема с этим подходом заключается в том, что они все равно могут передавать целое число, которое не отображается на страницу. Просто верните 404, если они это сделают, как и вы с "foo". Это не о чем беспокоиться, если у вас нет явных последствий для безопасности.