0

我有一个使用 RenderAction 调用视图的 Masterpage (site.master)。目前视图返回“hello world”。

网站主:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<html>
<head id="Head1" runat="server">
   <title><asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" /></title>
   <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server" />
</head>

<body>
    <% Html.RenderAction("Test", "Charts"); %>

    <asp:ContentPlaceHolder ID="ContentPlaceHolder3" runat="server" >
      <p>site.master</p>
    </asp:ContentPlaceHolder>

    <asp:ContentPlaceHolder ID="ContentPlaceHolder4" runat="server" />  
</body>
</html>

测试.aspx:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

hello world!

ChartsController.cs:

public ActionResult Test()
{
    return View();
}

如果我更新视图以明确传递 Masterpage 的名称,我在调用 RenderAction 时会收到错误消息。

ChartsController.cs:

public ActionResult Test()
{
    return View(null, "site");
}

错误:

内容控件必须是内容页或引用母版页的嵌套母版页中的顶级控件。

Stack Trace:

[HttpException (0x80004005): Content controls have to be top-level controls in a content page or a nested master page that references a master page.]
   System.Web.UI.MasterPage.CreateMaster(TemplateControl owner, HttpContext context, VirtualPath masterPageFile, IDictionary contentTemplateCollection) +8857854
   System.Web.UI.Page.get_Master() +54
   System.Web.UI.Page.ApplyMasterPage() +15
   System.Web.UI.Page.PerformPreInit() +45
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +328

如何设置我希望视图使用的母版页?最终,我将使用自定义 ViewEngine(通过覆盖 VirtualPathProviderViewEngine.FindView)动态设置 Masterpage。

if ( String.IsNullOrEmpty(masterName) ){ masterName = "site"; }

当我在 ViewEngine 中设置 masterName 属性,然后从 site.master 调用 RenderAction 时,我得到与在 Action 中设置 masterName 属性时相同的错误。

我正在使用:
Visual Studio 2010
MVC 3
IIS Express

编辑:添加了完整的 site.master 标记

4

2 回答 2

0

子类ViewPage<T>化并覆盖OnPreInit()事件。在您的覆盖中,

protected override void OnPreInit(EventArgs e)
{
    this.MasterLocation = GetMasterLocation();
    base.OnPreInit(e);
}

GetMasterLocation()方法应该获取视图的文件名(以“”开头~/)。

错误来自 中的CreateMaster方法MasterPage,抛出它的代码是:

if (masterPageFile == null)
{
    if ((contentTemplateCollection != null) && (contentTemplateCollection.Count > 0))
    {
        throw new HttpException(SR.GetString("Content_only_allowed_in_content_page"));
    }
    return null;
}

因此,MasterPage 不存在且内容模板集合具有模板,因此页面会引发异常。按照上述说明将以编程方式设置母版页的位置(它被处理为变量的虚拟路径masterPageFile

于 2011-03-03T02:59:52.733 回答
0

我已经想出了一个解决方案,并且至少对我的问题的原因有部分答案/理解。

如果我是正确的,问题是我试图在没有/不需要母版页的视图上设置母版页。我认为结果是我正在设置一个母版页的路径,即使该母版页存在,视图也没有预料到它并出现错误。

当我更新视图以使用母版页时,我能够将母版页的名称直接传递给视图而不会出错。

测试.aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Charts.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    hello world!
</asp:Content>

我在自定义 ViewEngine 中解决此问题的方法是检查当前 View 是否为 ChildAction。

if (String.IsNullOrEmpty(masterName) && !controllerContext.IsChildAction)
{
    masterName = "site";
}
于 2011-03-03T20:52:16.763 回答