Skip to main content
 首页 » 编程设计

c#之如何将自定义 WebViewPage 属性从 View 传递到布局

2024年04月18日36myhome

我已经定义了一个自定义 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; } 
  } 

在我看来,我将此属性设置为:

索引.cshtml:

@{ 
    OmniPageName = "Home"; 
} 

这在 View 中设置得很好并且可用,但我还需要在布局中访问这个值。我希望我可以从布局的 InitializePage() 覆盖中访问 View 实例,但我不知道如何访问。像这样的东西:

protected override void InitializePage() 
{ 
   //  this.OmniPageName = (expr:child view).OmniPageName 
   base.InitializePage(); 
} 

然后使用:

布局.cshtml:

<!-- render value from Index.cshtml --> 
<div class="pagelet" data-omnipage="@OmniPageName"></div>  

当前,此属性的 Layout 值为 null。我可以使用 ViewBag,但还有其他不简单的标量值属性,我想利用 IDE 的强类型强制来防止错误。

如有任何帮助,我们将不胜感激!

请您参考如下方法:

没有理由你不能完全按照你写的去做。

但是您需要确保将 web.Config 设置为所有 View 以继承您的自定义 View 页面。 (不确定这是否已经完成)。

在web.config找到 ~/Views/web.config文件夹设置pageBaseType到您的 View 类型。比如

<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通过继承自 WebViewPage<TModel> 为类型化模型.但是布局页面通常不键入。因此,您应该创建另一个继承自 BaseViewPage 的类比如

public class BaseViewPage : BaseViewPage<dynamic> 
{ 
     //functionality is inherited from BaseViewPage<T> 
} 

这将继承您的 Typed BaseViewPage 的所有功能并允许非类型化 View 。

编辑: 现在,如果您对此进行测试,您仍然不会将数据传递到布局页面,因为您会发现(设置构造函数断点)和 BaseViewPage 的新实例。为每个呈现的 View 创建。因此,您需要找到一种方法在实例之间的共享对象中传递数据。幸运的是,有许多不同的共享对象可用。

public string OmniPageName 
{ 
    get 
    { 
        return (ViewBag._OmniPageName ?? "").ToString(); 
    } 
    set 
    { 
        ViewBag._OmniPageName = value; 
    } 
} 

这是一个使用 ViewBag 的简单示例( <dynamic> ) 共享名称。我们可以使用:

  1. ViewData : 与ViewBag 基本相同但是是 Dictionary
  2. TempData :这类似于 ViewData但可以在请求之间持续存在。