回到目錄
DisplayNameFor方法是MVC提供給我們的,它可以将模型的DisplayName特性的值顯示到頁面上,這對程式員來說很是友善,在進行實體設計時,可以指定它的顯示名稱,然後MVC引擎會自動幫助我們生成DisplayNameFor代碼斷,而我們的所有字段的名稱就顯示到了頁面上,一切就這樣簡單,即使你在清單頁,你的模型IEnumerable<T>也可以很容易的被支援,而在大叔架構裡,分頁清單使用了模型PagedList<T>,這當然不會被微軟相容,是以,大叔為些特意為DisplayNameFor這個方法寫了一個擴充,讓它支援大叔的分頁,并且支援導航屬性的DisplayName,例如,UserInfo.UserExtension.NickName,它就會把UserExtension類的NickName字段的描述資訊顯示出來!
代碼屬于擴充方法,是以要寫在靜态類中,呵呵
/// <summary>
/// 大叔為DisplayName進行了擴充
/// </summary>
public static class DisplayNameExtensions
{
/// <summary>
/// 顯示字段的名稱DisplayName的值
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="html"></param>
/// <param name="expression"></param>
/// <returns></returns>
public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<PagedList<TModel>> html, Expression<Func<TModel, TValue>> expression)
{
Type t = typeof(TModel);
// string propertyName = GetPropertyName<TModel, TValue>(expression);
var complex = ExpressionHelper.GetExpressionText(expression).Split('.');
string propertyName = complex.Last();
if (complex.Count() > 1)
{
t = t.GetProperty(complex[complex.Length - 2]).PropertyType;
}
var p = t.GetProperty(propertyName);
if (p != null)
{
var attr1 = p.GetCustomAttribute(typeof(DisplayNameAttribute));
var attr2 = p.GetCustomAttribute(typeof(DisplayAttribute));
if (attr1 != null)
{
return MvcHtmlString.Create(((System.ComponentModel.DisplayNameAttribute)attr1).DisplayName);
}
if (attr2 != null)
{
return MvcHtmlString.Create(((DisplayAttribute)attr2).Name);
}
}
return MvcHtmlString.Create(string.Empty);
}
public static MvcHtmlString DisplayNameFor<TModel, TEnumerable, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, PagedList<TEnumerable>>> enumerableExpression, Expression<Func<TEnumerable, TValue>> valueExpression)
{
var metadata = ModelMetadata.FromLambdaExpression(valueExpression, new ViewDataDictionary<TEnumerable>());
string displayName = metadata.DisplayName ?? metadata.PropertyName ?? ExpressionHelper.GetExpressionText(valueExpression).Split('.').Last();
return new MvcHtmlString(HttpUtility.HtmlEncode(displayName));
}
}
運作的結果如圖
其實,在進行建立和編輯時,MVC為我們的DisplayNameFor已經實作了導航屬性的字段顯示功能,這個也是我在測試之後才發現的,呵呵
有一點還是要注意的,在表單元素上,你的導航屬性的字段命名是類名+字段名,而在id和name這兩個标簽中,又有不同,id是類名與字段之間用“下劃線”分開,而name是用“點”分開的,這點大家要清晰!
這一點如果Action在接收時使用的是FormCollection或者直接Request.Form時,就需要大家特别注意了,它們請求的是表單的name,而不是id,我們可以從圖中清晰的看到
而如果你的action中,參數使用的是實體,那麼MVC會幫助我們自動進行填充,省事了,呵呵!
好了,不早了,今天的MVC就說到這裡了!
感謝您的閱讀!
作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!
