2011-03-16 114 views
2

首先我有意見>博客> DisplayTemplates一個顯示模板:ASP.NET MVC 3顯示模板問題

@model Domain.Model.BlogPost 
<div class="blogSummary"> 
    @Html.ActionLink(Model.Title, "post", new { Id = Model.PostID }, new { @class = "titleLink" }) 
    <div class="subInfo"> 
     Posted by @Model.Author on @Model.PostedDate.ToString("D") | @Model.PostComments.Count 
     Comment(s)</div> 
    <br /> 
    <div class="summaryText"> 
     @Html.Markdown(Model.Body.Length > 300 ? Model.Body.Remove(0, 300) + "..." : Model.Body) 
     @Html.ActionLink("(view more)", "post", new { Id = Model.PostID }) 
    </div> 
</div> 

然後,我有一個觀點:

@model IEnumerable<Domain.Model.BlogPost> 
@{ 
    ViewBag.Title = "Index"; 
} 
@Html.DisplayFor(x => x, "BlogPostSummary") 

不過,我得到一個錯誤的DisplayFor()

傳遞到 字典型號產品類型'System.Data.Objects.ObjectSet`1 [Domain.Model.BlogPost]', 但該字典需要型號爲'Domain.Model.BlogPost'的 項目。

我在理解發生了什麼時遇到了一些麻煩。什麼是使用顯示模板的最佳方式?

回答

4

問題是,你正在嘗試傳遞一個BlogPosts的集合,當一個BlogPost的預期。

嘗試:

@Html.DisplayFor(x => x[0], "BlogPostSummary") 

或者類似的東西:

@foreach (var post in Model) 
    @Html.Display(post) 

注:我不認爲是正確使用Html.Display第二個例子。我的懷疑是使用部分代替顯示模板可以更好地使用代碼。

UIHint

默認情況下,ASP.NET MVC依靠命名約定鏈接BlogPost的類BlogPost.cshtml顯示模板。但是,如果您想使用CustomBlogPost.cshtml作爲顯示模板,則可以通過應用UIHint屬性來完成此操作。

public class DomainModel { 
    [UIHint("CustomBlogPost")] 
    public BlogPost Post { get; set; } 
} 
+1

有趣。在另一個應用程序中,我做了這個'@ Html.EditorFor(x => x.Guests)',它工作得很好。該視圖的模型是'Invite'類型的,其導航屬性爲'EntityCollection '類型的Guests。我沒有迭代集合;它自動完成了:/ – Chev 2011-03-16 19:48:35

+0

雖然我的感覺是在這一個,你應該使用部分而不是顯示模板。你有沒有任何理由? – kim3er 2011-03-16 19:57:05

+0

沒理由,我只是在另一個問題的某個地方被告知,以避免在我的視圖中循環收集並使用模板。看到接受的答案在這裏:http://stackoverflow.com/questions/5070399/how-to-use-multiple-form-elements-in-asp-net-mvc這就是他告訴我使用編輯器和顯示模板。 – Chev 2011-03-16 20:03:59

2

試試這個也許

@Html.DisplayFor(x => x.First(), "BlogPostSummary") 
+0

不知道爲什麼'[UIHint(...)]'在MVC 5.x中不起作用,但上面的工作。謝謝。 – Alex 2017-08-08 13:25:41

0

基本上它的,因爲這樣做的@Html.DisplayFor()隱含告訴MVC的模型傳遞是通過查看的模式,即IEnumerable<Domain.Model.BlogPost>

你需要什麼do是枚舉模型,並顯示它們中的每一個:

@foreach(var blogPost in Model){ 

    Html.RenderPartial("BlogPostSummary", blogPost) 

} 

確保BlogPostSummary位於正確的文件夾中,並且您應該很好走!

2

我一直在研究同樣的問題,我想我對你有更好的解決方案。您可以循環通過收集,仍然可以得到這個工作:

@foreach(var blogPost in Model) 
{ 
    Html.DisplayFor(x => blogPost, "BlogPostSummary") 
} 

使用上lambda表達式左邊的變量並不一定要求你也使用它的右側。 DisplayFor需要Expression<Func<TModel, TValue>>。TModel是您的模型的類型,例如IEnumerable<BlogPost>,但TValue可以是任何您喜歡的。所以只要你有一個對你的集合中的當前項的引用,就像在上面的foreach中一樣,你可以忽略lambda表達式的左邊。

(但你必須 tModel的。Html.DisplayFor(() => blogPost, "BlogPostSummary")不起作用。)

+0

正確的我知道我可以以這種方式循環(雖然它看起來很詭異,可能更適合部分視圖)。我的問題是,我喜歡顯示模板自動檢測到它正在傳遞一個模型類型的集合,並且隱式地循環/重複。不幸的是,這隻有在你爲模板使用適當的命名約定時纔有效。這意味着每個類型只有一個模板,並且我需要每種類型的多個模板。儘管謝謝你的回答! – Chev 2011-03-24 20:03:40

+1

我實際上正在做這樣的事情,上面的語法雖然看起來像*應該*工作,不會。你將能夠進入你的模板,但生成的HTML將永遠不會被渲染。你必須用'@'預先加入'Html.DisplayFor()'。通常這會讓你'在代碼塊中的一次你不需要預先聲明'@'錯誤,但顯然有一些特殊的規則.. http://stackoverflow.com/questions/17412113/mvc4-剃刀displaytemplate所謂-HTML生成的但不渲染到瀏覽器 – JoeBrockhaus 2013-07-01 20:13:44