我有一个使用RenderAction调用View的Masterpage(site.master)。目前View返回“hello world”。
的Site.Master:
<%@ 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>
Test.aspx文件:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
hello world!
ChartsController.cs:
public ActionResult Test()
{
return View();
}
如果我更新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)。
if ( String.IsNullOrEmpty(masterName) ){ masterName = "site"; }
当我在ViewEngine中设置masterName属性然后从site.master调用RenderAction时,我得到的错误与在Action中设置masterName属性时的错误相同。
我正在使用:
Visual Studio 2010
MVC 3
IIS Express
已编辑:已添加完整的site.master标记
答案 0 :(得分: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
)
答案 1 :(得分:0)
我提出了一个解决方案,至少部分回答/理解了我的问题。
如果我是正确的,问题是我试图在没有/不需要母版页的视图上设置母版页。我认为结果是我设置了一个主页的路径,即使该主页存在,View也不期望它并且通过错误。
当我更新View以使用Masterpage时,我能够将Masterpage的名称直接传递给View而没有错误。
Test.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";
}