Różnica między ViewResult () i ActionResult ()

295

Jaka jest różnica między ViewResult()i ActionResult()w ASP.NET MVC?

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

public ActionResult Index()
{
    return View();
}
Domnic
źródło
12
Świetne pytanie. Obejrzałem wideo i aby stworzyć testy jednostkowe, instruktor najpierw zmienił typ zwracanej akcji, którą miał przetestować z ActionResult na ViewResult. Bez wytłumaczenia… Byłem w stylu „Co możemy po prostu losowo zmieniać typy? Bez wyjaśnienia”
Doug Chamberlain
3
Prawdopodobnie ta dokumentacja jest pomocna :) msdn.microsoft.com/en-us/library/…
user3885927

Odpowiedzi:

372

ActionResult to klasa abstrakcyjna, która może mieć kilka podtypów.

Podtypy ActionResult

  • ViewResult - renderuje określony widok do strumienia odpowiedzi

  • PartialViewResult - renderuje określony widok częściowy do strumienia odpowiedzi

  • EmptyResult - zwracana jest pusta odpowiedź

  • RedirectResult - Wykonuje przekierowanie HTTP na określony adres URL

  • RedirectToRouteResult - Wykonuje przekierowanie HTTP na adres URL określony przez silnik routingu na podstawie danych trasy

  • JsonResult - Serializuje dany obiekt ViewData do formatu JSON

  • JavaScriptResult - zwraca fragment kodu JavaScript, który można wykonać na kliencie

  • ContentResult - zapisuje zawartość do strumienia odpowiedzi bez konieczności wyświetlania

  • FileContentResult - Zwraca plik do klienta

  • FileStreamResult - Zwraca plik do klienta, który jest dostarczany przez strumień

  • FilePathResult - Zwraca plik do klienta

Zasoby

Divi
źródło
5
Jaka jest zaleta zwracania ViewResult nad ActionResult - czy jest to nieco bardziej semantyczne i pokazuje twoje zamiary - ale w praktyce zwykle nie robi to różnicy?
niico,
121

ActionResult to klasa abstrakcyjna.

ViewResult wywodzi się z ActionResult . Inne pochodne klasy to JsonResult i PartialViewResult .

Deklarujesz to w ten sposób, abyś mógł skorzystać z polimorfizmu i zwrócić różne typy tą samą metodą.

na przykład:

public ActionResult Foo()
{
   if (someCondition)
     return View(); // returns ViewResult
   else
     return Json(); // returns JsonResult
}
RPM1984
źródło
2
Czy to oznacza, że ​​zawsze powinniśmy zwrócić ActionResult, abyśmy mogli z tego skorzystać. Czy jest to ograniczenie lub efekt uboczny?
Adarsh ​​Kumar
5
@Adarsh ​​- tak samo jest z każdą klasą abstrakcyjną w języku C #. Zadeklaruj to w ten sposób, jeśli chcesz enkapsulować implementację w metodzie lub chcesz w przyszłości sprawdzić API dla innych typów pochodnych. Jeśli nie, użyj betonu. Zazwyczaj używam betonu (np. ViewResult lub JsonResult)
RPM1984
31

Z tego samego powodu nie piszesz każdej metody każdej klasy, aby zwrócić „obiekt”. Powinieneś być jak najbardziej konkretny. Jest to szczególnie cenne, jeśli planujesz pisać testy jednostkowe. Nigdy więcej testowych typów zwrotów i / lub rzutowania wyniku.

RickAndMSFT
źródło
Na podstawie mojego doświadczenia korzystam z ViewResult przy czyszczeniu kodu i testowaniu jednostkowym.
JoshYates1980
20

ViewResult jest podklasą ActionResult. Metoda View zwraca ViewResult. Tak naprawdę te dwa fragmenty kodu robią dokładnie to samo. Jedyna różnica polega na tym, że w przypadku ActionResult kontroler nie obiecuje zwrócić widoku - możesz zmienić treść metody, aby warunkowo zwrócić RedirectResult lub coś innego bez zmiany definicji metody.

Robert Levy
źródło
11

Podczas gdy inne odpowiedzi poprawnie zauważyły ​​różnice, zauważ, że jeśli faktycznie zwracasz ViewResult, lepiej jest zwrócić bardziej konkretny typ niż podstawowy typ ActionResult. Oczywistym wyjątkiem od tej zasady jest sytuacja, gdy metoda zwraca wiele typów pochodzących z ActionResult.

Aby uzyskać pełne omówienie przyczyn tej zasady, zobacz pokrewną dyskusję tutaj: Czy metody kontrolera ASP.NET MVC muszą zwracać ActionResult?

Zaid Masud
źródło
4

W kontrolerze można użyć poniższej składni

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

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

W powyższym przykładzie zmienia się tylko typ zwrotu. jeden wraca, ViewResulta drugi wraca ActionResult.

ActionResult to klasa abstrakcyjna. Może zaakceptować:

ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePathResult itp.

ViewResultJest podklasą ActionResult.

ruchit
źródło
4
Nie jestem pewien, czy to właśnie miałeś na myśli, ale na wszelki wypadek chcę wyjaśnić, że nie możesz mieć tych dwóch metod w tym samym czasie, ponieważ ich nazwa i (nie) parametry są takie same. Nie można przeciążać metody, zmieniając tylko typ wyniku.
Andrew
0

W sterowniku określiłem poniższy kod za pomocą ActionResult, która jest klasą podstawową, która może mieć 11 podtypów w MVC, takich jak: ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePath.

    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
    }

Podobnie możemy zwrócić wszystkie te 11 podtypów za pomocą ActionResult () bez wyraźnego określenia każdej metody podtypu. ActionResult jest najlepszą rzeczą, jeśli zwracasz różne typy widoków.

Abhishek Duppati
źródło
0

Aby zaoszczędzić trochę czasu, tutaj jest odpowiedź z linku z poprzedniej odpowiedzi na https://forums.asp.net/t/1448398.aspx

ActionResult jest klasą abstrakcyjną i jest klasą podstawową dla klasy ViewResult.

W środowisku MVC używa klasy ActionResult, aby odwoływać się do obiektu zwracanego przez metodę akcji. I wywołuje na nim metodę ExecuteResult.

A ViewResult to implementacja dla tej abstrakcyjnej klasy. Spróbuje znaleźć stronę widoku (zwykle stronę aspx) w niektórych predefiniowanych ścieżkach (/ views / nazwa_kontrolera /, / views / shared / itp.) Według podanej nazwy widoku.

Zazwyczaj dobrą praktyką jest zwracanie przez metodę bardziej konkretnej klasy. Więc jeśli masz pewność, że twoja metoda akcji zwróci stronę przeglądania, możesz użyć ViewResult. Ale jeśli twoja metoda akcji może mieć inne zachowanie, na przykład renderowanie widoku lub przekierowanie. Możesz użyć bardziej ogólnej klasy bazowej ActionResult jako typu zwracanego.

wjxie
źródło