2013-11-28 52 views
4

我需要一個通用的內聯幫助程序來顯示字段。用於字段的ASP.NET MVC內聯幫助程序

這是我目前有:

@helper DisplayField(Func<MyModel, string> field) 
{ 
    if (string.IsNullOrWhiteSpace(field(Model)) == false) 
    { 
     <div class="row"> @field(Model) </div>  
    } 
} 

用法:

@DisplayField(m => m.Name) 
@DisplayField(m => m.PhoneNumber) 

我有一個助手裏面不知道如何顯示標籤(DisplayAttribute)。請幫忙。

回答

7

在頁面頂部,添加System.Linq.Expressions的使用,例如。

@using System.Linq.Expressions 

(或在web.config中添加此命名空間)。

然後創建幫手,它看起來是這樣的:

@helper DisplayField(Expression<Func<MyModel, string>> field) 
{ 
    @Html.LabelFor(field) 
    @Html.DisplayFor(field) 
} 

你可以在裏面添加額外的邏輯來檢查空值等等。你可能會更好,雖然創建的HtmlHelper,這樣你可以像上面那樣使用泛型類型參數而不是「MyModel」和「string」。當我上次嘗試時,不可能將泛型類型參數添加到內聯幫助程序中,例如。以下是可能的,除非這個功能已經添加:

@helper DisplayField<TModel, TValue>(Expression<Func<TModel, TValue>> field) 
{ 
    @Html.LabelFor(field) 
    @Html.DisplayFor(field) 
} 

因此,要獲得通用的方法,你可以使用自定義的HtmlHelper。要做到這一點:

  1. 創建類似如下的文件:

    using System; 
    using System.Linq; 
    using System.Linq.Expressions; 
    using System.Web; 
    using System.Web.Mvc; 
    using System.Web.Mvc.Html; 
    
    namespace MvcApplication1.HtmlHelpers 
    { 
        public static class HtmlHelpers 
        { 
         public static MvcHtmlString DisplayFieldFor<TModel, TValue>(
          this HtmlHelper<TModel> helper, 
          Expression<Func<TModel, TValue>> field) 
         { 
          var labelString = helper.LabelFor(field); 
          var displayString = helper.DisplayFor(field); 
    
          return MvcHtmlString.Create(
           labelString.ToString() + 
           displayString.ToString()); 
         } 
        } 
    } 
    
  2. 在您的網頁,這樣的事情的用法是:

    @Html.DisplayFieldFor(m => m.Name) 
    @Html.DisplayFieldFor(m => m.PhoneNumber) 
    

等。您可能需要在您的頁面上檢查您的使用情況,或者將HtmlHelper的名稱空間添加到web.config中。

+0

幾乎我需要的東西,除了如果它不是一個字符串它不起作用 – Andrei

1

@ David_001爲此提供了一個非常優雅的MVC解決方案;我將答案留在這裏,因爲它描述了內部機制,如果您需要解決MVC開箱即用的幫助程序未涉及的問題,可能會有所幫助。

將參數類型從Func<MyModel, string>更改爲Expression<Func<MyModel, string>>。這樣,您可以在您可以分析的方法中接收動態表達式,而不是在當前表單中收到的靜態委託。
您可以檢索字段的值是這樣的:

var compExpr = field.Compile(); 
var value = compExpr.DynamicInvoke(Model); 

您可以訪問該成員及其屬性由動態表達這樣的返回:

var memberAccExpr = (System.Linq.Expressions.MemberAccessExpression)field.Body; 
var attr = (DisplayAttribute)memberAccExpr.Member.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault(); 

我測試了它大致一個C#項目(而不是MVC),所以我不能說它是否適用於Razor;但我相信你也可以將你的代碼移動到一個普通的類。
請注意,由於調用者可以爲該方法提供各種動態表達式,因此您可以使用此方法釋放某些類型的安全性。因此,如果您分析表達式以查找屬性,則應考慮到這一點。