问题
I want to display different layouts based on the current rendered Page.
I can't find anything online about this but I feel like this should be an extremely common use case.
I only have a few pages. I would like to assign unique layouts to both my Register and Login pages.
This is what I've got so far but I am unable to use the ControllerContext in this situation.
@{
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
dynamic Layout;
switch (controllerName)
{
case "Register":
Layout = "_RegisterLayout";
break;
case "Login":
Layout = "_LoginLayout";
break;
default:
Layout = "_Layout";
break;
}
}
回答1:
We recently ran into a similar problem. We decided to provide the layout name with ViewData, Here's how.
Layout = (string)ViewData["LayoutName"] ?? "DefaultLayout";
This way you can change the layout using the action, or from inside the view or using an Action filter. I will include an Action filter that does the following using the Controller name, like you asked, and then you can register the filter globally.
public class LayoutNameFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
var result = context.Result as ViewResult;
var controllerName = context.RouteData.Values["controller"].ToString();
switch (controllerName)
{
case "Register":
result.ViewData["LayoutName"] = "_RegisterLayout";
break;
case "Login":
result.ViewData["LayoutName"] = "_LoginLayout";
break;
default:
result.ViewData["LayoutName"] = "_Layout";
break;
}
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
And then you can register this filter globally by replacing the services.AddMvc like this.
services.AddMvc(options =>
{
options.Filters.Add(new SampleFilter());
})
Hope this helps.
回答2:
As a convenience, the _ViewStart file is used to set the layout for all pages in the same folder as the ViewStart, and all its subfolders. You can override that in a number of ways, but the simplest way in your case is to specify a different value for the Layout
property in the Razor Page itself:
@page
@model MyApp.Pages.Account.LoginModel
@{
Layout = "/path/to/login-layout.cshtml;
}
<h1>Login</h1>
...
回答3:
You can try with ViewData. In the following code, I have changed the layout only for the contact page
Contact.cshtml.cs
public void OnGet()
{
ViewData["page"] = "Contact";
Message = "Your contact page.";
}
_ViewStart.cshtml
@{
if (ViewData["page"] != null && !string.IsNullOrWhiteSpace(ViewData["page"].ToString()))
{
Layout = "_ContactLayout";
}
else
{
Layout = "_Layout";
}
}
来源:https://stackoverflow.com/questions/57024115/how-can-i-set-up-conditional-layouts-with-viewstart-in-asp-net-core-razor-pages