How can I set up conditional Layouts with _ViewStart in ASP.NET Core Razor Pages?

怎甘沉沦 提交于 2020-05-28 07:57:34

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!