Como especifico layouts diferentes no arquivo ViewStart do ASP.NET MVC 3 razor?

313

Gostaria de ter 2 layouts separados no meu aplicativo. Digamos que um seja para a seção Pública do site e o outro seja para o lado Membro.

Para simplificar, digamos que toda a lógica de cada um desses sites seja organizada em 2 controladores distintos.

  • PublicController
  • StaffController

E que cada um deles tenha um Layout correspondente para toda a Visualização em cada um.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Como uso o arquivo _ViewStart.cshtml para especificar que todas as View / Action em "Public" usam o PublicLayout e tudo em "Staff" usa o StaffLayout?

Obrigado!

Justin
fonte
4
Apenas no caso: se você deseja remover o layout de uma determinada Razorexibição, basta definirLayout = null;
Leniel Maccaferri 19/03/2014
3
Apenas como um comentário no seu exemplo, você provavelmente não deve ter controladores chamados Public and Staff. Os controladores geralmente são implementados como o ponto de entrada para a ação do tipo CRUD em certas entidades comerciais importantes, como EventController, UserController ou similar. Se o seu aplicativo for razoavelmente grande, a responsabilidade de um controlador Público / Equipe seria muito ampla. Considere Áreas em vez disso. msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx Você pode estar ciente disso, mas alguém lendo isso pode ter uma ideia errada, portanto, apenas para o registro.
26614 Alex

Respostas:

558

Você pode colocar um _ViewStart.cshtmlarquivo dentro da /Views/Publicpasta que substituirá o padrão na /Viewspasta e especificar o layout desejado:

@{
    Layout = "~/Views/Shared/_PublicLayout.cshtml";
}

Por analogia, você pode colocar outro _ViewStart.cshtmlarquivo dentro da /Views/Staffpasta com:

@{
    Layout = "~/Views/Shared/_StaffLayout.cshtml";
}

Você também pode especificar qual layout deve ser usado ao retornar uma visualização dentro de uma ação do controlador, mas é por ação:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

Outra possibilidade é um filtro de ação personalizado que substituiria o layout. Como você pode ver muitas possibilidades para conseguir isso. Você decide qual deles se encaixa melhor no seu cenário.


ATUALIZAR:

Conforme solicitado na seção de comentários, veja um exemplo de filtro de ação que escolheria uma página mestre:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

e decore um controlador ou uma ação com este atributo personalizado, especificando o layout que você deseja:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}
Darin Dimitrov
fonte
1
@DarinDimitrov Onde vou criar LayoutInjecterAttribute. ? Existe algum local em particular?
Kbvishnu
2
@VeeKeyBee, você pode colocá-lo dentro de uma ActionFilterssubpasta.
Darin Dimitrov
Um possível problema com LayoutInjecterAttribute: É chamado antes do OnExceptionmétodo do controlador . Portanto, se o controlador fornecer um resultado de exibição durante o tratamento de exceções, o layout não será definido.
Jeff afiada
Como novato no MVC, gostaria de agradecer por me ensinar muito nesta resposta. No entanto, eu não entendo o que está acontecendo por dentro OnActionExecuted. Você pode atualizar a resposta para mim.
Imad
29

Mais um método é definir o layout dentro da tela:

   @{
    Layout = "~/Views/Shared/_MyAdminLayout.cshtml";
    }

Mais maneiras de fazer, podem ser encontradas aqui , espero que isso ajude alguém.

shaijut
fonte
1
Isso não funcionará - sem o _ViewStart.cshtml separado, sua visualização ainda será renderizada dentro do método @RenderBody () no outro layout.
usar o seguinte código
Este! Por que todos estão propondo esses processos extremamente complexos quando tudo que você precisa fazer é isso!
George Harnwell
15

Esse método é a maneira mais simples para iniciantes de controlar a renderização de layouts no aplicativo ASP.NET MVC. Podemos identificar o controlador e renderizar os Layouts como um controlador par. Para isso, podemos escrever nosso código no arquivo _ViewStart no diretório raiz da pasta Views. A seguir, um exemplo mostra como isso pode ser feito.

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

Leia o artigo completo aqui "Como renderizar layout diferente no asp.net MVC"

Anil Sharma
fonte