在部分剃刀视图中正确使用模型

时间:2015-06-21 10:55:29

标签: c# asp.net-mvc razor

我有以下控制器:

public class WelcomeController
{
        private IWelcomeService _service;

        public WelcomeController(IWelcomeService service)
        {
            _service = service;
        }

        public override ActionResult Index()
        {
            WelcomeIndexViewModel viewModel = new WelcomeIndexViewModel();
            viewModel.LatestNewsArticles = _service.GetLatestNewsArticles();
            return View(viewModel);
        }
}

以下是视图模型:

public class WelcomeIndexViewModel
{
    public IEnumerable<LatestNewsArticle> LatestNewsArticles { get; set; }
}

视图模型由一个服务填充,该服务填充WelcomeIndexViewModel中的LatestNewsArticles属性。

以下是视图的代码:

@model WelcomeIndexViewModel
@{
    ViewBag.Title = "Welcome";
 }
 <main class="main" role="main">
     <div class="container">
         <div class="row">
             <div class=“news col-xs-6 col-sm-6 col-md-6 col-lg-6">
                @Html.Partial(“LatestNews", Model)
             </div>
         </div>
     </div>
 </main>

以下是LatestNews的部分视图:

@model LatestNewsViewModel
<div class="latest-news">
    @foreach (LatestNewsArticle n in Model.LatestNewsArticles)
    {
        <h3><a href="@n.NewsArticleUrl" title="@n.Title">@n.Title</a></h3>
        <span class="featured-image">
            <img src="@FeaturedImageUrl" alt="@FeaturedImageAltText">
        </span>
        <p>@n.Summary</p>
    }
</div>

@model LatestNewsViewModel打破了视图,因为传递给它的模型不是LatestNewsViewModel。

如果我删除@model LatestNewsViewModel,那么如果传递的模型不包含正确的属性,我就不会在构建时遇到编译错误。

WelcomeIndexViewModel确实包含属性LatestNewsArticles,但由于它不是正确的类型,我收到编译错误。

我不确定将模型包含在另一个模型的属性中是否是一个好习惯,但我想这会起作用,但我真的想知道在这种情况下正确的解决方案是什么?

3 个答案:

答案 0 :(得分:1)

您正在将WelcomeIndexViewModel类型传递给部分,但指定会引发异常的部分接受类型LatestNewsViewModel

然后在部分中,您尝试遍历名为LatestNewsArticle的{​​{1}}属性(我怀疑它不存在)。

最好的方法是使用LatestNewsArticles类型DisplayTemplate

LatestNewsArticle

/Views/Shared/DisplayTemplates/LatestNewsArticle.cshtml

然后在主视图中:

@model yourAssembly.LatestNewsArticle

<h3>
    <a href="@Model.NewsArticleUrl" title="@Model.Title">@Model.Title</a>
</h3>
<span class="featured-image">
    <img src="@Model.FeaturedImageUrl" alt="@Model.FeaturedImageAltText">
</span>
<p>@Model.Summary</p>

请注意,@model WelcomeIndexViewModel @Html.DisplayFor(m => m.LatestNewsArticles) 同时接受单个对象@Html.DisplayFor()T

如果您希望IEnumerable<T>的模板特定于一个控制器,也可以将文件放在/Views/ControllerName/DisplayTemplates/LatestNewsArticle.cshtml中。

答案 1 :(得分:0)

尝试改变你的偏见:

@model WelcomeIndexViewModel
@{
    ViewBag.Title = "Welcome";
 }
 <main class="main" role="main">
     <div class="container">
         <div class="row">
             <div class="news col-xs-6 col-sm-6 col-md-6 col-lg-6">
                @Html.Partial("LatestNews", (object) Model.LatestNewsArticles)
             </div>
         </div>
     </div>
 </main>

然后......

@model IEnumerable<LatestNewsArticle>
<div class="latest-news">
    @foreach (LatestNewsArticle n in Model)
    {
        <h3><a href="@n.NewsArticleUrl" title="@n.Title">@n.Title</a></h3>
        <span class="featured-image">
            <img src="@n.FeaturedImageUrl" alt="@n.FeaturedImageAltText" />
        </span>
        <p>@n.Summary</p>
    }
</div>

也是一种很好的练习方法 Display and Editor Templates

答案 2 :(得分:-2)

使用Model.LatestNewsArticles :) 见下面的粗体:

@model WelcomeIndexViewModel
@{
    ViewBag.Title = "Welcome";
 }
 <main class="main" role="main">
     <div class="container">
         <div class="row">
             <div class=“news col-xs-6 col-sm-6 col-md-6 col-lg-6">
                @Html.Partial(“LatestNews", Model**.LatestNewsArticles**)
             </div>
         </div>
     </div>
 </main>

哦,然后在局部视图中使用IEnumerable:

@model IEnumerable<LatestNewsViewModel>
<div class="latest-news">
    @foreach (LatestNewsArticle n in Model)
    {
        <h3><a href="@n.NewsArticleUrl" title="@n.Title">@n.Title</a></h3>
        <span class="featured-image">
            <img src="@FeaturedImageUrl" alt="@FeaturedImageAltText">
        </span>
        <p>@n.Summary</p>
    }
</div>