在 ASP.NET MVC 中将数据传递到母版页

Posted

技术标签:

【中文标题】在 ASP.NET MVC 中将数据传递到母版页【英文标题】:Passing data to Master Page in ASP.NET MVC 【发布时间】:2010-09-09 20:43:23 【问题描述】:

您在不违反 MVC 规则的情况下将数据传递到母版页(使用 ASP.NET MVC)的方式是什么?

就个人而言,我更喜欢编写抽象控制器(基控制器)或传递给所有视图的基类。

【问题讨论】:

我写了一个关于我如何管理这个的指南:britishdeveloper.co.uk/2010/06/… 应该有帮助 【参考方案1】:

如果您希望您的视图具有强类型视图数据类,这可能对您有用。其他解决方案可能更正确,但恕我直言,这是设计和实用性之间的一个很好的平衡。

母版页采用强类型视图数据类,仅包含与其相关的信息:

public class MasterViewData

    public ICollection<string> Navigation  get; set; 

使用该母版页的每个视图都采用强类型视图数据类,其中包含其信息并派生自母版页视图数据:

public class IndexViewData : MasterViewData

    public string Name  get; set; 
    public float Price  get; set; 

由于我不希望各个控制器知道有关将母版页数据放在一起的任何信息,因此我将该逻辑封装到传递给每个控制器的工厂中:

public interface IViewDataFactory

    T Create<T>()
        where T : MasterViewData, new()


public class ProductController : Controller

    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    

继承很好地匹配主视图关系,但在渲染部分/用户控件时,我会将他们的视图数据组合到页面视图数据中,例如

public class IndexViewData : MasterViewData

    public string Name  get; set; 
    public float Price  get; set; 
    public SubViewData SubViewData  get; set; 


<% html.RenderPartial("Sub", Model.SubViewData); %>

这只是示例代码,并不打算按原样编译。专为 ASP.Net MVC 1.0 设计。

【讨论】:

这是 Scott Gutherie 推荐的方法,所以我不得不同意。 @Simon Fox - 有 scottgu 推荐的链接吗?没找到。 weblogs.asp.net/scottgu/archive/2007/12/06/… 对不起。理解其中的一部分有点困难。控制器的构造函数传递了一个 IViewDataFactory 的实例,但系统需要一个无参数的构造函数。我也不熟悉该接口的 C# 语法(特别是“MasterViewData,new()”)。有人可以解释一下还是给我一个好的资源。谢谢。 我喜欢使用强类型模型,但我不喜欢将主数据与我的所有其他模型和操作结合起来。进入这个线程有点晚了,但我发布了我的主数据方法,让事情变得更加松散。【参考方案2】:

我更喜欢将主视图的数据驱动部分拆分为部分并使用 Html.RenderAction 呈现它们。与流行的视图模型继承方法相比,这具有几个明显的优势:

    主视图数据与“常规”视图模型完全分离。这是组合优于继承,会产生更松散耦合的系统,更容易更改。 主视图模型由完全独立的控制器操作构建。 “常规”操作不需要担心这一点,也不需要视图数据工厂,这在我看来过于复杂。 如果您碰巧使用AutoMapper 之类的工具将您的域映射到您的视图模型,您会发现配置起来更容易,因为当您的视图模型不继承主视图时,它们将更接近于您的域模型数据。 通过主数据的单独操作方法,您可以轻松地将输出缓存应用到页面的某些区域。通常,主视图包含的数据更改频率低于主页内容。

【讨论】:

+1。另一个优点是您可以让同一个视图根据当前运行时状态使用不同的母版页。 我非常喜欢这个答案 - 概述的其他方法确实有点过于复杂。 这是我认为最优雅的解决方案。 这个解决方案对我来说也是最好的。谢谢一百万! 这是一个很好的方法,但请记住,您仍然必须指定“部分操作”的路线。看到这个答案***.com/a/3553617/56621【参考方案3】:

编辑

Generic Error 在下面提供了更好的答案。请阅读!

原答案

微软实际上已经在the "official" way 上发布了一个条目来处理这个问题。这提供了一个分步演练,并解释了他们的推理。

简而言之,他们建议使用抽象控制器类,但请自行查看。

【讨论】:

谢谢!这个例子正是我正在做的......来自数据库的每个页面上的类别。 Scott Gutherie,MVC 的作者之一推荐下面@Generic Error 提供的解决方案 +1 用于指导最佳答案,即使您的答案正式正确并被 OP 接受为答案。 +1 用于指导最佳答案,即使您的答案正式正确并被 OP 接受为答案。 其实,Todd Menier's 目前是最好的答案。【参考方案4】:

抽象控制器是个好主意,但我还没有找到更好的方法。我也很想看看其他人做了什么。

【讨论】:

【参考方案5】:

我做了一些研究,发现了这两个网站。也许他们可以提供帮助。

ASP.NET MVC Tip #31 – Passing Data to Master Pages and User Controls

Passing Data to Master Pages with ASP.NET MVC

【讨论】:

【参考方案6】:

我发现传递给视图的所有模型对象的共同父对象非常有用。

无论如何,页面之间总会有一些共同的模型属性。

【讨论】:

【参考方案7】:

Request.Params 对象是可变的。作为请求处理周期的一部分,向其添加标量值非常容易。从视图的角度来看,该信息可能已在 QueryString 或 FORM POST 中提供。 hth

【讨论】:

【参考方案8】:

我认为另一种好方法可能是使用某些属性(例如某些接口的 ParentView)为视图创建接口,因此您可以将它用于需要引用页面(父控件)的控件和应该用于主视图的主视图可以从视图中访问。

【讨论】:

【参考方案9】:

其他解决方案缺乏优雅且耗时太长。将近一年后,我为做了这件非常悲伤和贫困的事情而道歉:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    

    protected SiteMasterViewData MasterModel;
</script>

很明显,我在 SiteMasterViewData 上有这个静态方法 Get(),它返回 SiteMasterViewData。

【讨论】:

对于许多人来说,这可能看起来有点老套或“不干净”,但它可以快速完成工作 呃。如果您使用了 Html.RenderAction(),您的代码似乎更难维护。

以上是关于在 ASP.NET MVC 中将数据传递到母版页的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.Net MVC (LINQ) 中将嵌套数据从控制器传递到视图

在 ASP.Net MVC 5 中将 javascript 数组从视图传递到控制器

关于asp.net中页面事件加载的先后顺序

在 ASP.NET MVC 中将 ID 放在 <body> 上

ASP.NET MVC之路由特性以及母版页呈现方式

在 Asp.net MVC 中将值从视图传递到控制器