Разница между ViewResult () и ActionResult ()

295

В чем разница между ViewResult()и ActionResult()в ASP.NET MVC?

public ViewResult Index()
{
    return View();
}

public ActionResult Index()
{
    return View();
}
Domnic
источник
12
Отличный вопрос Я посмотрел видео, и для создания модульных тестов инструктор сначала изменил тип возвращаемого действия, которое он собирался протестировать, с ActionResult на ViewResult. Без объяснения .... Я был как «Что мы можем просто случайно изменить типы? Без объяснения»
Даг Чемберлен
3
Возможно , эта документация полезна :) msdn.microsoft.com/en-us/library/...
user3885927

Ответы:

372

ActionResult - это абстрактный класс, который может иметь несколько подтипов.

ActionResult Подтипы

  • ViewResult - отображает указанное представление в поток ответов.

  • PartialViewResult - визуализирует указанное частичное представление в поток ответов

  • EmptyResult - возвращается пустой ответ

  • RedirectResult - выполняет перенаправление HTTP на указанный URL

  • RedirectToRouteResult - выполняет перенаправление HTTP на URL-адрес, который определяется механизмом маршрутизации на основе заданных данных маршрута

  • JsonResult - сериализует данный объект ViewData в формат JSON

  • JavaScriptResult - возвращает фрагмент кода JavaScript, который может быть выполнен на клиенте

  • ContentResult - записывает содержимое в поток ответов без необходимости просмотра

  • FileContentResult - возвращает файл клиенту

  • FileStreamResult - возвращает файл клиенту, который предоставляется потоком

  • FilePathResult - возвращает файл клиенту

Ресурсы

Дива
источник
5
В чем преимущество возврата ViewResult по сравнению с ActionResult - это немного более семантически и показывает ваши намерения - но на практике обычно не имеет значения?
niico
121

ActionResult - это абстрактный класс.

ViewResult происходит от ActionResult . Другие производные классы включают JsonResult и PartialViewResult .

Вы объявляете это таким образом, чтобы использовать полиморфизм и возвращать разные типы в одном и том же методе.

например:

public ActionResult Foo()
{
   if (someCondition)
     return View(); // returns ViewResult
   else
     return Json(); // returns JsonResult
}
RPM1984
источник
2
Означает ли это, что мы всегда должны возвращать ActionResult, чтобы получить его преимущество? Или есть какое-то ограничение или побочный эффект этого?
Адарш Кумар
5
@Adarsh ​​- то же самое с любым абстрактным классом в C #. Объявите это таким образом, если вы хотите инкапсулировать реализацию внутри метода или хотите в будущем проверить свой API для других производных типов. Если нет, используйте бетон. Я обычно использую бетон (например, ViewResult или JsonResult)
RPM1984
31

По той же причине, по которой вы не пишете каждый метод каждого класса для возврата «объекта». Вы должны быть как можно более конкретны. Это особенно ценно, если вы планируете писать модульные тесты. Больше не нужно тестировать возвращаемые типы и / или приводить результат.

RickAndMSFT
источник
Более чистый код и модульное тестирование является преимуществом использования ViewResult, основываясь на моем опыте.
JoshYates1980
20

ViewResult является подклассом ActionResult. Метод View возвращает ViewResult. Так что на самом деле эти два фрагмента кода делают одно и то же. Единственное отличие состоит в том, что с ActionResult ваш контроллер не обещает возвращать представление - вы можете изменить тело метода для условного возврата RedirectResult или чего-то еще без изменения определения метода.

Роберт Леви
источник
11

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

Для полного обсуждения причин этого принципа, пожалуйста, смотрите соответствующее обсуждение здесь: Должны ли методы контроллера ASP.NET MVC возвращать ActionResult?

Зайд Масуд
источник
4

В контроллере можно использовать следующий синтаксис

public ViewResult EditEmployee() {
    return View();
}

public ActionResult EditEmployee() {
    return View();
}

В приведенном выше примере меняется только тип возвращаемого значения. один возвращается, ViewResultтогда как другой возвращается ActionResult.

ActionResult - это абстрактный класс. Он может принять:

ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePathResult и т. Д.

Это ViewResultподкласс ActionResult.

ruchit
источник
4
Я не уверен, что это именно то, что вы имели в виду, но на всякий случай хочу уточнить, что вы не можете использовать эти два метода одновременно, так как их имя и (нет) параметры совпадают. Перегрузить метод невозможно, только изменив тип результата.
Андрей
0

В Контроллере я указал приведенный ниже код с помощью ActionResult, который является базовым классом, который может иметь 11 подтипов в MVC, таких как: ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePreamResult, FilePreamResult.

    public ActionResult Index()
                {
                    if (HttpContext.Session["LoggedInUser"] == null)
                    {
                        return RedirectToAction("Login", "Home");
                    }

                    else
                    {
                        return View(); // returns ViewResult
                    }

                }
//More Examples

    [HttpPost]
    public ActionResult Index(string Name)
    {
     ViewBag.Message = "Hello";
     return Redirect("Account/Login"); //returns RedirectResult
    }

    [HttpPost]
    public ActionResult Index(string Name)
    {
    return RedirectToRoute("RouteName"); // returns RedirectToRouteResult
    }

Точно так же мы можем вернуть все эти 11 подтипов, используя ActionResult () без явного указания каждого метода подтипа. ActionResult - лучшая вещь, если вы возвращаете различные типы представлений.

Абхишек Дуппати
источник
0

Чтобы сэкономить ваше время, вот ответ по ссылке в предыдущем ответе на https://forums.asp.net/t/1448398.aspx.

ActionResult - это абстрактный класс, и это базовый класс для класса ViewResult.

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

И ViewResult является реализацией для этого абстрактного класса. Он попытается найти страницу просмотра (обычно aspx-страницу) по некоторым предопределенным путям (/ views / controllername /, / views / shared / и т. Д.) По заданному имени представления.

Обычно рекомендуется, чтобы ваш метод возвращал более конкретный класс. Поэтому, если вы уверены, что ваш метод действия вернет какую-либо страницу просмотра, вы можете использовать ViewResult. Но если у вашего метода действия может быть другое поведение, например, вы можете визуализировать представление или выполнить перенаправление. Вы можете использовать более общий базовый класс ActionResult в качестве возвращаемого типа.

wjxie
источник