2013-08-27 25 views
11

Chciałbym utworzyć pomocnika, który może być używany jakTworzenie niestandardowych Html Helper: MyHelperFor

@Html.MyHelperFor(m => m.Name) 

ten powinien powrócić na przykład

<span name="Name" data-something="Name"></span>

jeśli jest @Html.MyHelperFor(m => m.MailID) To powinno powrócić

<span name="MailID" data-something="MailID"></span>

Powinienem móc uzyskać dostęp do nazwy właściwości w metodzie pomocnika, aby ten typ pomocnika, jak sądzę.

Jak mogę to zrobić?

Odpowiedz

18

Możesz zrobić coś podobnego (poniższy zabierze również dodatkowe atrybuty HTML).

public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null) 
{ 
    var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); 
    string propertyName = data.PropertyName; 
    TagBuilder span = new TagBuilder("span"); 
    span.Attributes.Add("name", propertyName); 
    span.Attributes.Add("data-something", "something"); 

    if (htmlAttributes != null) 
    { 
     var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
     span.MergeAttributes(attributes); 
    } 

    return new MvcHtmlString(span.ToString()); 
} 
+3

To powinno być dodane wewnątrz klasy statycznej w przestrzeni nazw * System.Web.Mvc.Html *. – BornToCode

+0

@BornToCode Wiesz, zdecydowanie preferuję rozszerzenia napisane pod nazwą obszaru, do którego się odnoszą, w przeciwnym razie inni deweloperzy nigdy z nich nie skorzystają, jeśli nie znają ich tak, jak powinni wiedzieć o nich i przestrzeni nazw, żyć w celu dodania odniesienia i użycia go. – mattytommo

+0

Pytanie zadawane dla danych-coś = "MailID", gdzie twój ustawia go na "coś".Przykład musi pokazać, jak uzyskać wartość wyrażenia, a nie tylko nazwę właściwości. – xr280xr

2

To powinno wystartować. Ta funkcja bezpośrednio zwraca nazwę właściwości, ale powinnaś być w stanie ją przekonwertować do poszukiwanego rozszerzenia przy odrobinie pracy. Ten przykład ma poprawny podpis metody i wywołanie ExpressionHelper, aby uzyskać nazwę własności.

public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression) 
    { 
     string expressionName = ExpressionHelper.GetExpressionText(expression); 

     return new MvcHtmlString(expressionName); 
    } 
+0

To anser pomógł mi –

5

Można użyć metody FromLambaExpression od ModelMetadata tak:

namespace System.Web.Mvc.Html 
{ 
    public static class CustomHelpers 
    { 
     public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression) 
     { 
      var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); 
      var name = metaData.PropertyName; 
      // create your html string, you could defer to DisplayFor to render a span or 
      // use the TagBuilder class to create a span and add your attributes to it 
      string html = ""; 
      return new MvcHtmlString(html); 
     } 
    } 
} 

ModelMetadata klasa jest w przestrzeni nazw System.Web.Mvc. Metoda FromLambdaExpression jest używana przez wbudowanych pomocników, więc możesz mieć pewność, że Twój helper będzie działał tak samo, jak wbudowani pomocnicy. Umieszczając klasę CustomHelpers w przestrzeni nazw System.Web.Mvc.Html, możesz uzyskać dostęp do swojego pomocnika, tak jak inni pomocnicy, tj. @Html.MyHelperFor().

1

Nawiązując do odpowiedzi mattytommo, ten działa świetnie, ale jest tylko mały problem w przypadku korzystania z obiektów złożonych, takich jak w przypadku korzystania z tego kodu do nieruchomości znajdujących się wewnątrz EditorTemplate.

Zamiast

var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); 
string propertyName = data.PropertyName; 

przypadku korzystania MVC4, można go zmienić na

var propertyName = helper.NameFor(expression); 

lub MVC3 i poniżej

var propertyName = expression.Body.ToString(); 
propertyName = propertyName.Substring(propertyName.IndexOf(".") + 1); 
if (!string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix)) 
    propertyName = string.Format("{0}.{1}", helper.ViewData.TemplateInfo.HtmlFieldPrefix, propertyName); 

Pełny kod:

public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null) 
    { 
     var propertyName = expression.Body.ToString(); 
     propertyName = propertyName.Substring(propertyName.IndexOf(".") + 1); 
     if (!string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix)) 
      propertyName = string.Format("{0}.{1}", helper.ViewData.TemplateInfo.HtmlFieldPrefix, propertyName); 

     TagBuilder span = new TagBuilder("span"); 
     span.Attributes.Add("name", propertyName); 
     span.Attributes.Add("data-something", propertyName); 

     if (htmlAttributes != null) 
     { 
      var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
      span.MergeAttributes(attributes); 
     } 

     return new MvcHtmlString(span.ToString()); 
    } 
Powiązane problemy