Diferença entre ViewResult () e ActionResult ()

295

Qual é a diferença entre ViewResult()e ActionResult()no ASP.NET MVC?

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

public ActionResult Index()
{
    return View();
}
Domnic
fonte
12
Ótima pergunta. Eu assisti a um vídeo e, para criar testes de unidade, o instrutor primeiro alterou o tipo de retorno da ação que ele iria testar de ActionResult para ViewResult. Nenhuma explicação .... Eu era como "O que podemos apenas mudar aleatoriamente tipos Com nenhuma explicação?"
Doug Chamberlain
3
Provavelmente, esta documentação é útil :) msdn.microsoft.com/en-us/library/…
user3885927

Respostas:

372

ActionResult é uma classe abstrata que pode ter vários subtipos.

Subtipos ActionResult

  • ViewResult - Renderiza uma visualização especificada no fluxo de resposta

  • PartialViewResult - Renderiza uma visualização parcial especificada no fluxo de resposta

  • EmptyResult - Uma resposta vazia é retornada

  • RedirectResult - Executa um redirecionamento HTTP para um URL especificado

  • RedirectToRouteResult - Executa um redirecionamento HTTP para um URL determinado pelo mecanismo de roteamento, com base nos dados de rota fornecidos

  • JsonResult - serializa um determinado objeto ViewData para o formato JSON

  • JavaScriptResult - Retorna um pedaço de código JavaScript que pode ser executado no cliente

  • ContentResult - Grava conteúdo no fluxo de resposta sem exigir uma visualização

  • FileContentResult - Retorna um arquivo para o cliente

  • FileStreamResult - Retorna um arquivo para o cliente, fornecido por um Stream

  • FilePathResult - Retorna um arquivo para o cliente

Recursos

Divi
fonte
5
qual é a vantagem de retornar o ViewResult sobre o ActionResult - é apenas um pouco mais semântico e mostra sua intenção - mas na prática geralmente não faz diferença?
Niico 19/10/16
121

ActionResult é uma classe abstrata.

O ViewResult deriva do ActionResult . Outras classes derivadas incluem JsonResult e PartialViewResult .

Você o declara dessa maneira para poder tirar proveito do polimorfismo e retornar tipos diferentes no mesmo método.

por exemplo:

public ActionResult Foo()
{
   if (someCondition)
     return View(); // returns ViewResult
   else
     return Json(); // returns JsonResult
}
RPM1984
fonte
2
Isso significa que sempre devemos retornar o ActionResult para obter a vantagem disso. Ou existe alguma limitação ou efeito colateral disso?
Adarsh Kumar
5
@ Adarsh ​​- é o mesmo com qualquer classe abstrata em c #. Declare-o dessa maneira, se você quiser encapsular a implementação dentro do método ou desejar à prova futura sua API para outros tipos digitados. Caso contrário, use o concreto. Geralmente uso o concreto (por exemplo, ViewResult ou JsonResult)
RPM1984
31

É pela mesma razão que você não escreve todos os métodos de todas as classes para retornar "objeto". Você deve ser o mais específico possível. Isso é especialmente valioso se você planeja escrever testes de unidade. Chega de testar tipos de retorno e / ou converter o resultado.

RickAndMSFT
fonte
O código mais limpo e o teste de unidade são o benefício de usar o ViewResult com base na minha experiência.
JoshYates1980
20

ViewResult é uma subclasse de ActionResult. O método View retorna um ViewResult. Então, esses dois trechos de código fazem exatamente a mesma coisa. A única diferença é que, com o ActionResult, seu controlador não promete retornar uma exibição - você pode alterar o corpo do método para retornar condicionalmente um RedirectResult ou qualquer outra coisa sem alterar a definição do método.

Robert Levy
fonte
11

Enquanto outras respostas observaram as diferenças corretamente, observe que, se você está retornando apenas um ViewResult, é melhor retornar o tipo mais específico, em vez do tipo ActionResult base. Uma exceção óbvia a esse princípio é quando seu método retorna vários tipos derivados de ActionResult.

Para uma discussão completa dos motivos por trás desse princípio, consulte a discussão relacionada aqui: Os métodos do controlador ASP.NET MVC devem retornar ActionResult?

Zaid Masud
fonte
4

No controlador, pode-se usar a sintaxe abaixo

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

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

No exemplo acima, apenas o tipo de retorno varia. um retorna ViewResultenquanto o outro retornaActionResult .

ActionResult é uma classe abstrata. Pode aceitar:

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

O ViewResulté uma subclasse de ActionResult.

ruchit
fonte
4
Não tenho certeza se foi isso que você quis dizer, mas apenas para esclarecer que você não pode ter esses dois métodos ao mesmo tempo, pois o nome e os parâmetros (no) são os mesmos. Não é possível sobrecarregar um método alterando apenas o tipo de resultado.
Andrew
0

No Controller, especifiquei o código abaixo com ActionResult, que é uma classe base que pode ter 11 subtipos no MVC, como: ViewResult, PartialViewResult, EmptyResult, RedirectResult, RedirectToRouteResult, JsonResult, JavaScriptResult, ContentResult, FileContentResult, FileStreamResult, FilePathResult.

    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
    }

Da mesma forma, podemos retornar todos esses 11 subtipos usando ActionResult () sem especificar explicitamente todos os métodos de subtipos. O ActionResult é a melhor coisa se você estiver retornando diferentes tipos de visualizações.

Abhishek Duppati
fonte
0

Para economizar algum tempo, aqui está a resposta de um link em uma resposta anterior em https://forums.asp.net/t/1448398.aspx

ActionResult é uma classe abstrata e é base para a classe ViewResult.

Na estrutura MVC, ele usa a classe ActionResult para referenciar o objeto que seu método de ação retorna. E invoca o método ExecuteResult nele.

E o ViewResult é uma implementação para essa classe abstrata. Ele tentará encontrar uma página de visualização (geralmente página aspx) em alguns caminhos predefinidos (/ views / nome do controlador /, / views / shared /, etc) com o nome de visualização fornecido.

Geralmente, é uma boa prática fazer com que seu método retorne uma classe mais específica. Portanto, se você tiver certeza de que seu método de ação retornará alguma página de exibição, use o ViewResult. Mas se o seu método de ação pode ter um comportamento diferente, como renderizar uma exibição ou executar um redirecionamento. Você pode usar a classe base mais geral ActionResult como o tipo de retorno.

wjxie
fonte