Exibir uma exibição de outro controlador no ASP.NET MVC

248

É possível exibir uma visão de outro controlador?

Digamos, por exemplo, que eu tenho uma CategoriesControllere uma Category/NotFound.aspxvisão. Enquanto estiver no CategoriesController, posso voltar facilmente View("NotFound").

Agora diga que eu tenho ProductsControlleruma ação e uma visualização para adicionar um produto. No entanto, essa ação exige que tenhamos uma categoria à qual adicionar o produto. Por exemplo Products/Add/?catid=10,.

Se eu não conseguir encontrar a categoria com base catid, quero mostrar a NotFoundexibição do controlador Categorias em vez de criar uma CategoryNotFoundexibição no controlador Produtos.

Isso é possível ou estou estruturando as coisas da maneira errada? Existe uma boa maneira de fazer isso?

dtc
fonte

Respostas:

283

Sim. Por padrão, o ASP.NET MVC faz check-in primeiro \Views\[Controller_Dir]\, mas depois disso, se não encontrar a exibição, faz check-in \Views\Shared.

O diretório compartilhado existe especificamente para compartilhar Views entre vários controladores. Basta adicionar sua exibição ao subdiretório compartilhado e pronto.

Se fizer isso, return View("~/Views/Wherever/SomeDir/MyView.aspx")você pode retornar qualquer visualização que desejar.

womp
fonte
Obrigado, isso soa como a solução que eu deveria estar usando. Ainda me pergunto se é possível exibir uma View de outro controlador. Eu estou supondo que isso viola alguma regra no MVC?
dtc
1
Na situação descrita acima, sim, você deve estar usando a pasta compartilhada.
1113 Jonathan Freeland
69
Sim, isso também é possível. Se você retornar o modo de exibição ("~ / Views / Wherever / SomeDir / MyView.aspx"), poderá retornar o modo de exibição que desejar. Isso não viola nenhuma regra específica, porém, o ASP.Net MVC tem tudo a ver com "convenção sobre configuração". Em outras palavras, a estrutura foi criada para operar automaticamente usando certas convenções, e você deve utilizá-la sempre que possível.
Womp
1
Obrigado pela explicação. Eu não sabia que Views poderia ser chamado assim. O diretório compartilhado é claro funciona perfeitamente :)
dtc
1
Eu não estava em um Controller, então eu tive que usar new ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" };e funcionou
Nacht
162

Você pode usar:

return View("../Category/NotFound", model);

Foi testado no ASP.NET MVC 3, mas também deve funcionar no ASP.NET MVC 2.

Guillaume86
fonte
3
Funciona no MVC 2 e acabou sendo a solução mais limpa para uma situação incomum com a qual estou lidando.
Todd Menier 02/02
3
O Re-compartilhador relatará esse link como um erro, mas ainda funciona.
CodeMonkeyKing
1
@CodeMonkeyKing - O resharper 7 (no VS2012) identifica corretamente um caminho formatado como "~/Views/Category/NotFound.cshtml".
Richard Ev
Vale ressaltar: esta solução funciona com modos de exibição, por exemplo, se você tivesse uma visualização "/Category/NotFound.Mobile.cshtml".
BenWillkommen
55

Sim é possivel. Retorne um RedirectToAction()método como este:

return RedirectToAction("ActionOrViewName", "ControllerName");
doncadavona
fonte
1
Eu acredito que isso deve ir como RedirectToAction ("ActionOrView", "Controller", null), caso contrário, o segundo paramater é routeValues
Zoran P.
Mas, neste caso, você deve realmente escrever a ação no controlador, ao contrário da solução View.
precisa saber é o seguinte
@ tobbenb3 Essa é uma solução muito melhor do que codificar um resultado. De qualquer maneira, você não deve passar uma string de caminho.
perustaja 14/02
34

Você já tentou RedirectToAction?

Paul Johnson
fonte
1
Eu diria que este é o MVC para qualquer pessoa que não queira a visualização em pastas compartilhadas; observe que para todas as outras soluções (como o uso de caminhos diretos), qualquer pessoa que tentar redimensionar as visualizações não precisará ter em mente que também está a ser usado em outro controlador, resultando em um comportamento imprevisível
halb yoel
4
que tal sem redirecionar?
Luckyy
maneira melhor solução do que mudar o ponto de vista de pastas compartilhadas
jufo
Esta solução requer ação no controlador, o View (directPath) renderiza a saída sem nenhuma ação. Quando você adiciona uma ação, você precisa ocultá-la do acesso direto via url, isso gera um passo no histórico do navegador etc. Mas sim, é o meu caminho.
Jan Zahradník
3
RedirectToAction envia um código de resposta 302 para o navegador. Isso não é apropriado quando você está tentando mostrar uma página 404 não encontrada. Ou seja, essa solução parece funcionar, mas confundirá os mecanismos de pesquisa.
precisa saber é o seguinte
20

Sim você pode. Retorne uma ação como esta:

return RedirectToAction("View", "Name of Controller");

Um exemplo:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees");

Essa abordagem chamará o método GET

Além disso, você pode passar valores para ações como esta:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees", new {id = id.ToString(), viewtype = "extended" });
ignacio chiazzo
fonte
como eu enviaria um objeto com essa abordagem?
Djeroen 23/01
Dê uma olhada @Djeroen
Ignacio chiazzo
5
Você não está retornando uma visualização, está chamando uma ação.
0014 de
Acima de tudo, foi útil para mim.
anil shrestha
5

Você também pode chamar qualquer controlador de JavaScript / jQuery . Digamos que você tenha um controlador retornando 404 ou algum outro controle / página do usuário. Em seguida, em alguma ação, a partir do código do cliente, você pode chamar algum endereço que acionará seu controlador e retornar o resultado em formato HTML . O código do cliente pode pegar esse resultado retornado e colocá-lo onde quiser na sua página ...

Marko
fonte
Eu não sabia disso. Parece que é algo que eu poderia usar no futuro. Sim, mvc rocks :)
dtc
1

Com este código, você pode obter qualquer controlador:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, 
controller);
Yair GR
fonte
Tradução: Com este código, você pode obter qualquer controlador: [código], Atenciosamente,
Robert Columbia
3
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de como e / ou por que ele resolve o problema melhoraria o valor a longo prazo da resposta.
precisa saber é o seguinte