[英]Use Html.DisplayNameFor with IEnumerable<IGrouping>
[英]Html.DisplayNameFor List vs IEnumerable in Razor
我正在實現教程中的PaginatedList 。
有用。 如果我在我的 Razor 頁面@model
定義為IEnumerable
我可以這樣做:
@model IEnumerable<CustomerDisplayViewModel>
@Html.DisplayNameFor(model => model.LastName)
如果我將@model
定義為List
,則@Html.DisplayNameFor
助手的工作方式不同,我必須這樣稱呼它:
@model List<CustomerDisplayViewModel>
@Html.DisplayNameFor(model => model.First().LastName)
不同之處在於,在第一次調用中,表達式將 model 轉換為CustomerDisplayViewModel
而在第二次調用中它是List<CustomerDisplayViewModel>
。
該問題是由編譯器傾向於將調用轉換為
Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
string DisplayNameFor<TResult>(Expression<Func<TModel, TResult>> expression);
代替
Microsoft.AspNetCore.Mvc.Rendering.HtmlHelperDisplayNameExtensions
public static string DisplayNameFor<TModelItem, TResult>(
this IHtmlHelper<IEnumerable<TModelItem>> htmlHelper, Expression<Func<TModelItem, TResult>> expression);
我知道我可以使用我的解決方法( @Html.DisplayNameFor( model => model.First().LastName)
),但感覺不正確。
有沒有辦法進行調用或者生成我自己的調用 IEnumerable 擴展的擴展(我不希望從頭開始創建擴展,這個調用應該與 IEnumerable 完全一樣)。 我可以使用 List<> 創建擴展方法,但是我無法轉換它。
public static string DisplayNameFor<TModelItem, TResult>
(this Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<List<TModelItem>> htmlHelper,
Expression<Func<TModelItem, TResult>> expression)
{
var castHelper = --- somehow cast helper to IHtmlHelper<IEnumerable<TModelItem>
return castHelper.DisplayNameFor(expression);
}
謝謝。
發生這種情況是因為IHtmlHelper
的泛型參數TModel
不是covariant 。 基本上,你不能這樣做:
IHtmlHelper<List<CustomerDisplayViewModel>> helperList = new HtmlHelper<List<CustomerDisplayViewModel>(...);
IHtmlHelper<IEnumerable<CustomerDisplayViewModel>> helperIEnumerable = helperList;
// the above line is an error
但是,您可以使用IEnumerable<T>
來做到這一點:
IEnumerable<int> intList = new List<int>();
IEnumerable<object> objList = intList; // no error
這是因為IEnumerable
是這樣聲明的:
public interface IEnumerable<out T> : IEnumerable { .. }
注意out
關鍵字,它指定泛型參數T
是協變的。 如果IHtmlHelper<TModel>
在框架中這樣聲明:
interface IHtmlHelper<out TModel> { .. }
你的代碼會起作用的。
盡管如此,在這種情況下,您仍然可以使用Html.DisplayNameForInnerType()
來獲取顯示名稱(僅限 ASP.NET Core):
@model PaginatedList<CustomerDisplayViewModel>
...
@Html.DisplayNameForInnerType((CustomerDisplayViewModel c) => c.LastName)
請注意,您必須明確指定 lambda 表達式參數的類型。( CustomerDisplayViewModel c
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.