如何在ASP.NET Core Razor页面中使用_ViewStart设置条件布局?

时间:2019-07-14 02:21:43

标签: c# asp.net razor-pages

我想根据当前渲染的页面显示不同的布局。

我在网上找不到任何相关信息,但我觉得这应该是一个非常普遍的用例。

我只有几页。我想为“注册”和“登录”页面分配唯一的布局。

这是目前为止我所能做的,但是在这种情况下我无法使用ControllerContext。

@{
    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;
    }
}

enter image description here

5 个答案:

答案 0 :(得分:1)

以上所有方法都没有为我解决问题,但以下解决方案适用于我使用 .net 5 razor 页面。

注意:我根据pages文件夹设置了布局页面

RelativePath 为您提供 url 相对路径,如“/Pages/Admin/Index.cshtml”,然后我将路径拆分为字符串数组。从数组我得到 使用 pathArray[2] 的文件夹名称。

var path = ((Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor)ViewContext.ActionDescriptor).RelativePath;
string[] pathArray = path.Split('/');
string pageFolder = pathArray[2];
if (pageFolder != null && pageFolder.ToLower()=="admin")
{
    Layout = "_AdminLayout";
}
else
{
    Layout = "_Layout";
}

答案 1 :(得分:0)

我们最近遇到了类似的问题。我们决定为布局名称提供ViewData,方法如下。

Layout = (string)ViewData["LayoutName"] ?? "DefaultLayout";

通过这种方式,您可以使用动作或从视图内部或使用动作过滤器来更改布局。我将包含一个Action过滤器,该过滤器将按照您的要求使用Controller名称执行以下操作,然后您可以在全局范围内注册该过滤器。


    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)
        {
        }
    }

然后您可以通过替换服务在全球范围内注册此过滤器。Addmvc就像这样。

services.AddMvc(options =>
            {
                options.Filters.Add(new SampleFilter());
            })

希望这会有所帮助。

答案 2 :(得分:0)

为方便起见,_ViewStart文件用于为ViewStart所在的同一文件夹中的所有页面及其所有子文件夹设置布局。您可以通过多种方法来覆盖它,但是最简单的方法是为Razor页面本身中的Layout属性指定一个不同的值:

@page
@model MyApp.Pages.Account.LoginModel
@{
    Layout = "/path/to/login-layout.cshtml;
}
<h1>Login</h1>
...

答案 3 :(得分:0)

您可以尝试使用ViewData。在以下代码中,我仅更改了联系页面的布局

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";
    }
}

答案 4 :(得分:0)

df1文件中尝试一下:

df2

这是一个对我有用的例子