【问题标题】:The layout page "~/Views/Shared/" could not be found at the following path在以下路径中找不到布局页面“~/Views/Shared/”
【发布时间】:2026-01-28 19:05:01
【问题描述】:

这是对这个旧错误的新转折。我的许多页面都使用布局页面,所以它们在顶部附近有这个

@{
    Layout = "~/Views/Shared/" + ViewBag.layout;
}

viewbag 布局在应用于控制器的动作过滤器中设置

namespace somenamespace.Controllers {
    [SessionSettings]
    public class MyController : Controller {

动作过滤器在哪里做这个

public class SessionSettings : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        dynamic viewBag = filterContext.Controller.ViewBag;
        string layout = some database lookup
        if (layout == null) layout = "_defaultLayout.cshtml";
        viewBag.layout = layout

这在大多数情况下都非常有效。但是当我检查事件日志 - 应用程序 - 我看到警告,事件 ID 1309,事件代码 3005,“发生未处理的异常”“在以下路径中找不到布局页面“~/Views/Shared/”: “~/Views/Shared/”。”

这是最重要的,通常事件发生在不使用布局的页面上,他们在顶部有这个

@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>...

有人对此有任何想法吗?谢谢

【问题讨论】:

  • 你调试它并观看 ViewBag.layout 了吗?也许试试:Layout = "~/Views/Shared/" + ViewBag.layout ?? ""
  • 我想建议另一种方法:How to set a Razor layout in MVC via an attribute filter?,您可以使用传递自定义名称的选项扩展该属性。这样,只有在没有提供属性时才会使用 Viewstart。
  • W92 - 不幸的是,该错误从未在我的机器上发生过,并且在生产中它是间歇性的。
  • @Silvermind - 我对此进行了调查,基本上我正在做同样的事情。他们只是使用 OnResultExecuting 而不是 OnActionExecuting。为什么会有不同?
  • @nuander 它不会滥用 ViewBag 并且可以正常工作。

标签: c# asp.net-mvc


【解决方案1】:

我查了源码发现问题出在你设置Layout = "~/Views/Shared/" + ViewBag.layout;的时候

设置此属性后,将调用方法WebPageExecutingBase.NormalizeLayoutPagePath(string path)

这基本上创建了一个绝对/相对路径,然后检查是否存在具有该名称的 文件。因为ViewBag.layout 为空,所以这会失败,所以会出错(您可以在codeplex 上查看此方法的源代码,大约一半。

后面设置Layout = null没关系,先调用_ViewStart代码才会出现错误。

我能看到的最佳选择是在设置之前检查ViewBag.layout 是否为空:

if(ViewBag.layout != null)
{
    Layout = "~/Views/Shared/" + ViewBag.layout;
}

我认为这样的话,如果他们没有布局,你也不需要显式地将其设置为null

【讨论】:

  • 我认为Layout = "~/Views/Shared/" + ViewBag.layout ?? "" 的语法更短。
  • 好的,我会检查这个 _ViewStart 并报告
  • 嗯,我没有使用 ViewStart,所以我不确定这是否适用
  • @W92 如果没有设置ViewBag.layoutLayout = "~/Views/Shared/" + ViewBag.layout ?? "" 仍然会给出"~/Views/Shared/",这与OP 完全相同。
  • 检查 null 是个好主意,我会将其添加到我的代码中,谢谢
最近更新 更多