Должны ли методы ASP.NET MVC Controller возвращать ActionResult?

Будучи новичком в ASP.NET MVC, я задавался вопросом о подписи методов controllerа. Во всех примерах, которые я видел, они всегда возвращают ActionResult, даже если они действительно возвращают экземпляр ViewResult или похожи.

Вот типичный пример:

public ActionResult Index() { return this.View(); } 

В таком случае, не имеет смысла объявлять этот метод как public ViewResult Index() и получать более сильную поддержку типов?

Эксперимент показывает, что это работает, поэтому кажется возможным.

Я понимаю, что могут быть ситуации, когда требуется polymorphism (например, если вы хотите перенаправить только в определенных ситуациях, но показывать представление в других ситуациях), но если метод всегда возвращает представление, я бы нашел ViewResult больше желательно.

Что касается будущей совместимости, ActionResult, очевидно, обеспечивает более надежную подпись, но если управлять всей базой кода, всегда можно изменить подпись метода на более общий тип возврата, если это станет необходимым в будущем.

Являются ли какие-либо другие соображения, о которых я не знаю, или я должен идти дальше и объявлять методы controllerа с конкретными типами возврата?

Вы можете абсолютно использовать конкретные типы возвращаемых данных, хотя большинство примеров в Интернете, похоже, возвращают ActionResult . Единственный раз, когда я возвращал class ActionResult, – это когда разные пути метода действия возвращают разные подтипы.

Стивен Сандерсон также рекомендует возвращать определенные типы в своей книге Pro ASP.NET MVC Framework . Взгляните на приведенную ниже цитату:

«Этот метод действий специально объявляет, что он возвращает экземпляр ViewResult. Он будет работать одинаково, если вместо этого тип возвращаемого метода был ActionResult (базовый class для всех результатов действия). На самом деле некоторые программисты ASP.NET MVC объявляют все свои как возвращать неспецифический ActionResult, даже если они точно знают, что он всегда будет возвращать один конкретный подclass. Однако в объектно-ориентированном программировании хорошо установленный принцип, чтобы методы возвращали наиболее специфический тип, который они могут (а также принимая самые общие типы параметров, которые они могут). Следуя этому принципу, вы получаете максимальную удобство и гибкость для кода, который вызывает ваш метод, например, ваши модульные тесты ».

Всегда возвращайте наиболее точный тип, который вы можете вернуть. Поэтому вы должны вернуть ViewResult, когда действие всегда показывает представление. Я бы использовал ActionResult, когда вы возвращаетесь в ViewResult в некоторых случаях (недопустимые отправленные данные) или RedirectToRouteResult в других случаях.

С помощью некоторого расширенного сценария actionfilter / executing вы можете даже вернуть совершенно разные вещи, которые не имеют никакого отношения к ActionResult.

[Частичный ответ]: вы не всегда возвращаете ActionResult, нет. Вот краткий обзор некоторых других результатов, которые вы можете вернуть: http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.98%29.aspx

Может быть, это поможет немного. Удачи!

Да, вы можете определить свое действие как: public ViewResult Index() . Но иногда ваше действие может возвращать разные результаты (это невозможно без объявления результата в качестве базового classа ActionResult ). Например:

 public ActionResult Show() { ... if(Request.IsAjaxRequest()) { return PartialView(...); } return View(...); } 

или:

 public ActionResult Show() { ... try { ... } catch(Exception) { return RedirectToAction(...); } return View(...); } 

ActionResult – это базовый class для различных типов возвращаемых данных. Таким образом, ваше действие должно вернуть ActionResult или class, полученный из него , чтобы работать. Обычными являются ViewResult , ViewResult и т. Д.

Да, у меня есть книга Сандерсона, и мне эта часть понравилась, потому что это было чем-то досадно, когда я смотрел на другие примеры действий controllerа. Моя философия даже b4-обучения MVC заключалась в том, что поскольку функции (методы, возвращающие значение) должны обрабатываться так, как если бы вы объявляли переменную / быть подставляемой в контексте для переменной / ref того же типа, будьте конкретны в отношении типа, поскольку вы если бы объявление var (подумайте об этом как о желании избежать определения всех ваших переменных типа «Объект» в приложении – более надежным, но вы потеряете некоторую проверку времени и тип безопасности). Облегчает проверку блока controllerа для правильного типа возврата.

Для справки см. Также «Принцип замещения Либкова» («L» в «SOLID»).

Interesting Posts

Разрешения Android M: onRequestPermissionsResult () не вызывается

iOS 7: Как получить собственный номер через частный API?

Какая лучшая файловая система для внешнего USB-накопителя – 2 – 3 ТБ, распределенная между OSX / Windows / Linux?

Выводит как stderr, так и stdout в файл, и только stderr в командной строке

Поиск процента в подгруппе с использованием group_by и суммирование

Нажмите «Один раз» – все пользователи

Каков наилучший способ повторения нескольких или более контейнеров одновременно

Попытка прикрепить файл с SD-карты к электронной почте

Бесконечная recursion с выпуском Jackson JSON и Hibernate JPA

Координаты текстуры OpenGL в пиксельном пространстве

Новый GPU жужжит, разогревает и не выключит вентиляторы (ON IDLE)

Как вставить шрифт с помощью моего приложения на C #? (с использованием Visual Studio 2005)

Как работает разбиение на Spark?

Есть ли способ автоматически уменьшить громкость сабвуфера ночью?

Отключение выхода Log4J в Java

Давайте будем гением компьютера.