Действие MVC с дополнительными параметрами - что лучше?
Есть ли какие-либо плюсы и минусы использования следующих двух альтернатив в вашей сигнатуре действия:
public ActionResult Action(int? x) // get MVC to bind null when no parameter is provided
{
if(x.HasValue)
{
// do something
}
}
ИЛИ
public ActionResult Action(int? x = null) // C# optional parameter (virtual overload)
{
if(x.HasValue)
{
// do something
}
}
Ответы
Ответ 1
Я никогда не видел вторую сигнатуру действия на практике и не вижу никакой пользы от нее.
Первый, как правило, охватывает все сценарии:
- Если параметр не отправлен (
GET /somecontroller/action
), значение аргумента x будет равно нулю внутри действия
- Если передается x-параметр, но он не является допустимым целым числом (
GET /somecontroller/action?x=abc
), значение аргумента x будет равно null внутри действия, и модельное состояние будет недействительным
- Если отправляется x-параметр и значение представляет действительное целое число (
GET /somecontroller/action?x=123
), то ему присваивается x.
В моих примерах я использовал запросы GET с параметрами строки запроса, но, очевидно, то же самое относится к другим глаголам HTTP, и если x
был параметром маршрута.
Ответ 2
Вам нужно указать необязательное значение параметра, если оно будет чем-то другим, кроме null
.
MVC3 автоматически установит null
в качестве значения вашего параметра, если ничего не указано в перегрузке или в вызове Action.
Однако стоит отметить, что если после этого параметра в сигнатуре есть какие-либо необязательные параметры, в вызове должно быть указано null
.
Поэтому лучше всего поставить все необязательные параметры в конце подписи.
Ответ 3
Лучшее решение Asp.net MVC - используйте селектор действия действий
Почему бы не упростить методы действий контроллера, удалив ненужную ветвь кода и получив такой код:
public ActionResult Index()
{
// do something when there no id
}
[RequiresRouteValues("id")]
public ActionResult Index(int id)
{
// do something when id is present
}
Это, конечно, возможно, если вы предоставите очень простой код для селектора действий RequiresRouteValuesAttribute
. Вы можете найти код в этом сообщении в блоге, который делает именно это.
По моему мнению, это наилучшее решение этой проблемы, потому что:
- Это упрощает код, удаляя ненужную ветку
- Делает код более удобным для обслуживания (из-за меньшей сложности)
- Расширяет структуру MVC Asp.net как можно и должна
- Сохраняет типы параметров, как они должны быть, без необходимости их пропускания.
- и др.
В любом случае. Все подробности об этой технике подробно описаны в связанной записи.