2011-06-01 75 views
8

是否有任何可能的方式來擴展基本的HTML幫助器(TextBoxFor,TextAreaFor等)在其輸出上使用擴展方法,而不是隻重寫整個方法徹底?舉例來說,在加...ASP.NET MVC - 擴展TextBoxFor而不重寫方法

@Html.TextBoxFor(model => model.Name).Identity("idName")

我知道我可以在此使用以下,已經達到..

@Html.TextBoxFor(model => model.Name, new { @id = "idName" })

但是得到笨重和令人沮喪的管理,當你有開始添加很多屬性。有沒有什麼辦法可以爲這些內容添加擴展名,而不必爲每個細節都傳遞htmlAttributes

回答

9

由於@AaronShockley說,因爲TextBoxFor()返回MvcHtmlString,你開發修改輸出的「流體API的風格只會選擇是由輔助方法返回的MvcHtmlString s運行。這樣做,我想稍微不同的方式接近你以後會使用「屬性生成器」的對象,像這樣:

public class MvcInputBuilder 
{ 
    public int Id { get; set; } 

    public string Class { get; set; } 
} 

...並設立擴展方法是這樣的:

public static MvcHtmlString TextBoxFor<TModel, TProp>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TProp>> expression, 
    params Action<MvcInputBuilder>[] propertySetters) 
{ 
    MvcInputBuilder builder = new MvcInputBuilder(); 

    foreach (var propertySetter in propertySetters) 
    { 
     propertySetter.Invoke(builder); 
    } 

    var properties = new RouteValueDictionary(builder) 
     .Select(kvp => kvp) 
     .Where(kvp => kvp.Value != null) 
     .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 

    return htmlHelper.TextBoxFor(expression, properties); 
} 

那麼你可以做這樣的東西在你的視野:

@this.Html.TextBoxFor(
    model => model.Name, 
    p => p.Id = 7, 
    p => p.Class = "my-class") 

這給了你強類型和智能輸入特性,您可以通過添加親自定義每個擴展方法熟悉適當的MvcInputBuilder子類。

6

所有基本的html幫助程序都會返回System.Web.Mvc.MvcHtmlString類型的對象。您可以爲該類設置擴展方法。這裏有一個例子:

public static class MvcHtmlStringExtensions 
{ 
    public static MvcHtmlString If(this MvcHtmlString value, bool check) 
    { 
     if (check) 
     { 
      return value; 
     } 

     return null; 
    } 

    public static MvcHtmlString Else(this MvcHtmlString value, MvcHtmlString alternate) 
    { 
     if (value == null) 
     { 
      return alternate; 
     } 

     return value; 
    } 
} 

然後你就可以像一個視圖中使用這些:

@Html.TextBoxFor(model => model.Name) 
    .If(Model.Name.StartsWith("A")) 
    .Else(Html.TextBoxFor(model => model.LastName) 

要作出這樣的修改所提供的HTML標記屬性擴展方法,你就必須轉換結果到一個字符串,並找到並替換您正在尋找的值。

using System.Text.RegularExpressions; 

public static MvcHtmlString Identity(this MvcHtmlString value, string id) 
{ 
    string input = value.ToString(); 
    string pattern = @"(?<=\bid=")[^"]*"; 
    string newValue = Regex.Replace(input, pattern, id); 
    return new MvcHtmlString(newValue); 
} 

public static MvcHtmlString Name(this MvcHtmlString value, string id) 
{ 
    string input = value.ToString(); 
    string pattern = @"(?<=\bname=")[^"]*"; 
    string newValue = Regex.Replace(input, pattern, id); 
    return new MvcHtmlString(newValue); 
} 

idname屬性總是由HTML輔助添加,但是如果你想與屬性可能不會在那裏工作(你就必須添加它們,而不是僅僅更換他們的),你將需要修改代碼。