Должны ли методы ASP.NET MVC Controller возвращать ActionResult? - PullRequest
56 голосов
/ 20 июня 2009

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

Вот наиболее распространенный пример:

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

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

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

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

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

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

Ответы [ 6 ]

57 голосов
/ 20 июня 2009

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

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

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

13 голосов
/ 20 июня 2009

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

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

8 голосов
/ 20 июня 2009

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

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

7 голосов
/ 20 июня 2009

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

public ActionResult Show()
{
    ...

    if(Request.IsAjaxRequest())
    {
        return PartialView(...);
    }

    return View(...);
}

или

public ActionResult Show()
{
    ...

    try
    {
        ...
    }
    catch(Exception)
    {
        return RedirectToAction(...);
    }

    return View(...);
}
3 голосов
/ 20 июня 2009

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

2 голосов
/ 15 марта 2012

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

Для получения соответствующей справки см. Также принцип замещения Листкова («L» в «ТВЕРДОМ»).

...