ChatGPT解决这个技术问题 Extra ChatGPT

如何在 ASP.NET MVC 3 razor ViewStart 文件中指定不同的布局?

我想在我的应用程序中有 2 个单独的布局。假设一个用于网站的公共部分,另一个用于会员端。

为简单起见,假设每个站点的所有逻辑都整齐地包装在 2 个不同的控制器中。

公共控制器

员工控制器

并且它们每个都有一个对应的布局,用于每个视图下的所有视图。

_PublicLayout.cshtml

_StaffLayout.cshtml

如何使用 _ViewStart.cshtml 文件来指定“Public”下的所有视图/操作都使用 PublicLayout,而“Staff”下的所有内容都使用 StaffLayout?

以防万一:如果您想删除给定 Razor 视图的布局,只需设置 Layout = null;
就像对您的示例的评论一样,您可能不应该拥有名为 Public 和 Staff 的控制器。控制器通常被实现为对某些关键业务实体(如 EventController、UserController 等)进行类似 CRUD 的操作的入口点。如果您的应用程序相当大,那么 Public/Staff 控制器的职责范围就会很广。改为考虑区域。 msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx 您可能知道这一点,但其他阅读此内容的人可能会产生错误的想法,因此仅作记录。

D
Darin Dimitrov

您可以将 _ViewStart.cshtml 文件放在 /Views/Public 文件夹中,该文件将覆盖 /Views 文件夹中的默认文件并指定所需的布局:

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

以此类推,您可以将另一个 _ViewStart.cshtml 文件放入 /Views/Staff 文件夹中:

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

您还可以指定在控制器操作中返回视图时应使用哪种布局,但这是每个操作:

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

另一种可能性是自定义操作过滤器,它将覆盖布局。如您所见,实现这一目标的可能性很多。由您决定哪一个最适合您的场景。

更新:

根据评论部分的要求,这是一个选择母版页的操作过滤器示例:

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

然后使用此自定义属性装饰控制器或操作,指定您想要的布局:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}

@DarinDimitrov 我将在哪里创建 LayoutInjecterAttribute。 ?有什么特别的位置吗?
@VeeKeyBee,您可以将其放在 ActionFilters 子文件夹中。
LayoutInjecterAttribute 的一个潜在问题是:它在控制器的 OnException 方法之前被调用。因此,如果控制器在异常处理期间提供视图结果,则不会设置布局。
S
Shaiju T

另一种方法是在视图中定义布局:

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

更多方法,可以找到here,希望这对某人有所帮助。


这将不起作用 - 如果没有单独的 _ViewStart.cshtml,您的视图仍将在其他布局的 @RenderBody() 方法中呈现。
这个!为什么大家都在提出这些极其复杂的过程,而你需要做的就是这个!
M
Machavity

此方法是初学者在 ASP.NET MVC 应用程序中控制布局呈现的最简单方法。我们可以识别控制器并将 Layouts 渲染为 par 控制器,为此我们可以在 Views 文件夹根目录的 _ViewStart 文件中编写代码。以下是一个示例,说明如何完成。

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