天天看點

愛上MVC~為DisplayNameFor添加擴充,支援PagedList集合

回到目錄

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

支付寶掃一掃,為大叔打賞!

愛上MVC~為DisplayNameFor添加擴充,支援PagedList集合