我已经定义了一个自定义WebViewPage类型,其中包含我们网站使用的自定义属性:
public abstract class BasePage : WebViewPage
{
public string OmniPageName { get; set; }
}
public abstract class BasePage<TModel> : WebViewPage<TModel> where TModel: class
{
public string OmniPageName { get; set; }
}
在我看来,我将此属性设置为:
Index.cshtml:
@{
OmniPageName = "Home";
}
这在视图中设置得很好并且可用,但我还需要在布局中访问此值。我希望我可以从布局的InitializePage()覆盖中访问视图实例,但我无法弄清楚如何。类似的东西:
protected override void InitializePage()
{
// this.OmniPageName = (expr:child view).OmniPageName
base.InitializePage();
}
然后使用:
Layout.cshtml:
<!-- render value from Index.cshtml -->
<div class="pagelet" data-omnipage="@OmniPageName"></div>
目前,此属性的布局值为null。我可以使用ViewBag但是还有其他属性并不简单,标量值,我想利用IDE执行强类型来防止错误。
非常感谢任何帮助!
答案 0 :(得分:3)
你没有理由不像你所写的那样完全这样做。
但是,您需要确保将web.Config设置为从自定义视图页面继承的所有视图。 (不确定这是否已经完成)。
在web.config
找到~/Views/web.config
文件夹中,将pageBaseType
设置为您的视图类型。如
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="YourNameSpace.BasePage"> <!-- Edit This line -->
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<!-- ommited -->
</namespaces>
</pages>
</system.web.webPages.razor>
现在我们可以看到,通过继承WebViewPage
,您只能为Typed模型设置自定义WebViewPage<TModel>
。但是,通常不会键入布局页面。因此,您应该创建另一个继承自BaseViewPage
的类,例如
public class BaseViewPage : BaseViewPage<dynamic>
{
//functionality is inherited from BaseViewPage<T>
}
这将继承您键入的BaseViewPage
的所有功能,并允许非类型化视图。
修改强>
现在,如果你测试这个,你仍然不会将数据传递给Layout页面,因为你会发现(设置一个构造函数断点),并为每个呈现的View创建一个新的BaseViewPage
实例。因此,您需要找到一种在实例之间传递共享对象中数据的方法。幸运的是,有许多不同的共享对象可用。
public string OmniPageName
{
get
{
return (ViewBag._OmniPageName ?? "").ToString();
}
set
{
ViewBag._OmniPageName = value;
}
}
这是一个使用ViewBag
(<dynamic>
)来共享名称的简单示例。我们可以使用:
ViewData
:基本上与ViewBag
相同,但是Dictionary
TempData
:这与ViewData
类似,但可以在请求之间保留。