it-swarm.cn

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

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

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

102
Łukasz Sowa

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

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

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

77
Generic Error

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

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

_编辑_

通用错误 在下面提供了更好的答案。请仔细阅读!

原始答案

微软实际上发布了一个条目 “官方”方式 来处理这个问题。这提供了一步一步的演练,并解释了他们的推理。

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

20
Michael La Voie

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

7
Ian P

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

ASP.NET MVC提示#31 - 将数据传递到母版页和用户控件

使用ASP.NET MVC将数据传递到母版页

3
David Negron

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

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

2
Matt Mitchell

我还有另外一个好方法可以创建一个视图接口,使用某些属性,如某些接口的ParentView,这样你就可以将它用于需要引用页面的控件(父控件)和应该从中访问的主视图观点。

0
dimarzionist

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

<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()。

0
rasx

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

0
mtutty