Asp.Net MVC布局和部分视图

时间:2021-02-09 03:27:54

let's consider two views that use the same layout composed of:

让我们考虑两个使用相同布局的视图:

  • A left column containing a "body" (which is filled differently by both views)
  • 左栏包含“正文”(两个视图的填充方式不同)
  • A right column that displays general information (passed via the model)
  • 右栏显示一般信息(通过模型传递)

Instead of defining the right part twice, I wondered if I could create a PartialView to link directly from the layout page.

而不是两次定义正确的部分,我想知道我是否可以创建一个PartialView直接从布局页面链接。

The problem is that the partial views implicitely inherit their models from the view that is being rendered. And since each view has its own model, I end up with a model type mismatch in the partial view.

问题是部分视图从正在呈现的视图中隐含地继承了它们的模型。由于每个视图都有自己的模型,因此我在局部视图中最终会出现模型类型不匹配的情况。

From here I see two solutions:

从这里我看到两个解决方案:

  • I could insert the common part of the view model in the ViewBag. Unfortunately this means that each view that uses this layout has to implement this "convention" but nothing warns the developer about it at compile time...
  • 我可以在ViewBag中插入视图模型的公共部分。不幸的是,这意味着使用此布局的每个视图都必须实现此“约定”,但在编译时没有任何内容警告开发人员...
  • I could use polymorphism to make each view model inherit from the same base class (edit: or interface) that the Partial Views uses. This would work up to a certain extend but would potentially exponentially increase in complexity as soon as I have a second partial view in the same layout.
  • 我可以使用多态来使每个视图模型继承自部分视图使用的相同基类(编辑:或接口)。这将在一定程度上起作用,但只要我在同一布局中有第二个局部视图,就可能以指数方式增加复杂性。

So here are the questions:

以下是问题:

  • Am I right with the assumptions above?
  • 我对上述假设是否正确?
  • Do you see any other possibility?
  • 你还有其他可能吗?
  • Any return on experience on this?
  • 对此有何回报?

Thanks a lot, TB.

非常感谢,TB。

3 个解决方案

#1


7  

Use an Interface and implement it on the two models, this is exactly the kind of thing they're used for.

使用一个接口并在两个模型上实现它,这正是他们用来做的事情。

Here is an example of two different Views using two different Models that both implement an interface. This is subtyping instead of ad-hoc polymorphism.

下面是两个不同视图的示例,它们使用两个不同的模型来实现接口。这是子类型而不是ad-hoc多态。

public class ViewModelOne : IReusableView
{
    public string Name { get; set; }
    public string Something { get; set; }
    public int ANumber { get; set; }
}

public class ViewModelTwo : IReusableView
{
    public string Name { get; set; }
    public string Thing { get; set; }
    public string SomethingElse { get; set; }
    public int ANumber2 { get; set; }
}

public interface IReusableView
{
    string Name { get; }
}

So we have the really simple partial view here that is 'InnerPartialView':

所以我们这里有一个非常简单的局部视图,即'InnerPartialView':

@model TestIntegration.Models.IReusableView
<div>
    @Model.Name
</div>

Which is used in the home and about pages of this example controller:

在家庭和本示例控制器的页面中使用的是:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View(new ViewModelOne() { Name = "hello", Something="sdfsdfs", ANumber = 1 });
        }

        public ActionResult About()
        {
            return View(new ViewModelTwo() { Name = "hello 2", SomethingElse = "aaaddd", ANumber2 = 10, Thing="rand" });
        }
    }

The home view:

主页视图:

@model TestIntegration.Models.ViewModelOne
@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    @Html.Partial("InnerPartialView")
</p>

The about view:

关于观点:

@model TestIntegration.Models.ViewModelTwo
@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
         @Html.Partial("InnerPartialView")
</p>

#2


3  

When you render the partial view, you can send it a model:

渲染局部视图时,可以向其发送模型:

@Html.RenderPartial(MVC.Partials.Views.Sidebar, Model.SideBarModel);

So you could send down data as part of the parent model that is the model for the partial sidebar.

因此,您可以将数据作为父模型的一部分发送,该模型是部分侧边栏的模型。

#3


-1  

In partial views, models are of type dynamic so you don't need to know what type they are. However, you just need to make sure the model has the property you need. In other words you can use Model.MyProperty or Model.MyProperty as MyPropertyType when using Html.Partial.

在部分视图中,模型属于动态类型,因此您无需知道它们的类型。但是,您只需确保模型具有您需要的属性。换句话说,在使用Html.Partial时,可以使用Model.MyProperty或Model.MyProperty作为MyPropertyType。

#1


7  

Use an Interface and implement it on the two models, this is exactly the kind of thing they're used for.

使用一个接口并在两个模型上实现它,这正是他们用来做的事情。

Here is an example of two different Views using two different Models that both implement an interface. This is subtyping instead of ad-hoc polymorphism.

下面是两个不同视图的示例,它们使用两个不同的模型来实现接口。这是子类型而不是ad-hoc多态。

public class ViewModelOne : IReusableView
{
    public string Name { get; set; }
    public string Something { get; set; }
    public int ANumber { get; set; }
}

public class ViewModelTwo : IReusableView
{
    public string Name { get; set; }
    public string Thing { get; set; }
    public string SomethingElse { get; set; }
    public int ANumber2 { get; set; }
}

public interface IReusableView
{
    string Name { get; }
}

So we have the really simple partial view here that is 'InnerPartialView':

所以我们这里有一个非常简单的局部视图,即'InnerPartialView':

@model TestIntegration.Models.IReusableView
<div>
    @Model.Name
</div>

Which is used in the home and about pages of this example controller:

在家庭和本示例控制器的页面中使用的是:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View(new ViewModelOne() { Name = "hello", Something="sdfsdfs", ANumber = 1 });
        }

        public ActionResult About()
        {
            return View(new ViewModelTwo() { Name = "hello 2", SomethingElse = "aaaddd", ANumber2 = 10, Thing="rand" });
        }
    }

The home view:

主页视图:

@model TestIntegration.Models.ViewModelOne
@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    @Html.Partial("InnerPartialView")
</p>

The about view:

关于观点:

@model TestIntegration.Models.ViewModelTwo
@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
         @Html.Partial("InnerPartialView")
</p>

#2


3  

When you render the partial view, you can send it a model:

渲染局部视图时,可以向其发送模型:

@Html.RenderPartial(MVC.Partials.Views.Sidebar, Model.SideBarModel);

So you could send down data as part of the parent model that is the model for the partial sidebar.

因此,您可以将数据作为父模型的一部分发送,该模型是部分侧边栏的模型。

#3


-1  

In partial views, models are of type dynamic so you don't need to know what type they are. However, you just need to make sure the model has the property you need. In other words you can use Model.MyProperty or Model.MyProperty as MyPropertyType when using Html.Partial.

在部分视图中,模型属于动态类型,因此您无需知道它们的类型。但是,您只需确保模型具有您需要的属性。换句话说,在使用Html.Partial时,可以使用Model.MyProperty或Model.MyProperty作为MyPropertyType。