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

时间:2008-09-17 00:08:40

标签: c# .net asp.net asp.net-mvc

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

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

9 个答案:

答案 0 :(得分:77)

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

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

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设计。

答案 1 :(得分:59)

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

  1. 主视图数据与“常规”视图模型完全分离。这是继承的组合,导致更松散耦合的系统更容易改变。
  2. 主视图模型由完全独立的控制器操作构建。 “常规”操作不需要担心这一点,并且不需要视图数据工厂,这似乎对我的口味过于复杂。
  3. 如果您碰巧使用像AutoMapper这样的工具将您的域映射到您的视图模型,您会发现它更容易配置,因为当您的视图模型不继承时,它们将更像您的域模型主视图数据。
  4. 使用主数据的单独操作方法,您可以轻松地将输出缓存应用于页面的某些区域。通常,主视图包含的变化频率低于主页面内容。

答案 2 :(得分:20)

修改

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

原始答案

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

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

答案 3 :(得分:7)

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

答案 4 :(得分:3)

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

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

Passing Data to Master Pages with ASP.NET MVC

答案 5 :(得分:2)

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

其他解决方案缺乏优雅,需要很长时间。几乎整整一年后,我为这件非常悲伤和贫困的事情道歉:

<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上有这个返回SiteMasterViewData的静态方法Get()。