2009-08-22 6 views
23

Dans asp.net mvc je vois toujours les aides html intégrées, ils ont toujours l'objet htmlAttirbutes.Comment obtenir des valeurs hors de l'objet HtmlAttributes

Ensuite, je fais généralement de nouveaux {@id = "test", @ class = "myClass"}.

Comment puis-je extraire un paramètre comme celui-ci dans mes propres aides html? Comme je suis en train d'utiliser "HtmlTextWriterTag", c'est comme ça que je peux transmettre cet objet entier à l'écrivain et le comprendre ou quoi?

Aussi comment cela fonctionne avec de gros helpers html?

Comme je fais une aide html et il utilise toutes ces étiquettes. Est-ce que cela signifie que je dois créer un attribut html pour chacune de ces balises?

Répondre

36

je fais quelque chose comme ceci:

public static string Label(this HtmlHelper htmlHelper, string forName, string labelText, object htmlAttributes) 
    { 
     return Label(htmlHelper, forName, labelText, new RouteValueDictionary(htmlAttributes)); 
    } 

    public static string Label(this HtmlHelper htmlHelper, string forName, string labelText, 
           IDictionary<string, object> htmlAttributes) 
    { 
     // Get the id 
     if (htmlAttributes.ContainsKey("Id")) 
     { 
      string id = htmlAttributes["Id"] as string; 
     } 

     TagBuilder tagBuilder = new TagBuilder("label"); 
     tagBuilder.MergeAttributes(htmlAttributes); 
     tagBuilder.MergeAttribute("for", forName, true); 
     tagBuilder.SetInnerText(labelText); 
     return tagBuilder.ToString(); 
    } 

Je vous suggère de télécharger la source ASP.NET MVC de la CodePlex et jeter un oeil à la construction dans les aides html.

+0

s'avère que votre exemple est plus informatif que la source. Je n'arrivais pas à comprendre comment la source fonctionnait comme on attendait un IDictionary (comme votre label), mais j'essayais de lui passer l'objet anonyme. Une fois que je vous ai vu le convertir en RouteValueDictionary est plus logique. –

+2

Cela ne semble pas fonctionner avec des attributs comme data_bind – SimonGates

3

vous pouvez transformer l'objet htmlAttirbutes à une représentation de chaîne attribut/valeur comme ceci:

var htmlAttributes = new { id="myid", @class="myclass" }; 

string string_htmlAttributes = ""; 
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes)) 
{ 
    string_htmlAttributes += string.Format("{0}=\"{1}\" ", property.Name.Replace('_', '-'), property.GetValue(htmlAttributes)); 
} 

PropertyDescriptor appartiennent à la classe System.ComponentModel

1

J'utilise un mélange des deux méthodes (Chtiwi Malek et rrejc) proposé plus tôt et cela fonctionne très bien. Par cette méthode, il convertira data_id en data-id. Il écrase également les valeurs d'attribut par défaut que vous avez définies précédemment.

using System.ComponentModel; 
... 


public static MvcHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes) 
{ 
    var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); 

    string htmlFieldName = ExpressionHelper.GetExpressionText(expression); 
    string labelText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last(); 

    if (String.IsNullOrEmpty(labelText)) 
     return MvcHtmlString.Empty; 

    var label = new TagBuilder("label"); 
    label.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); 

    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(htmlAttributes)) 
    { 
     // By adding the 'true' as the third parameter, you can overwrite whatever default attribute you have set earlier. 
     label.MergeAttribute(prop.Name.Replace('_', '-'), prop.GetValue(htmlAttributes).ToString(), true); 
    } 
    label.InnerHtml = labelText; 
    return MvcHtmlString.Create(label.ToString()); 
} 

Notez le commentaire sur l'écrasement d'un attribut qui a une valeur par défaut dans votre code dans foreach.

Questions connexes