2011-08-01 1 views
1

J'ai besoin de lancer mon propre assistant BeginLabel pour Mvc. J'ai vérifié/volé le concept de la source Mvc pour les méthodes html.beginForm/ajax.beginForm.Implémenter .net mvc BeginLabel comme BeginForm response.write issue

public static Label BeginLabel(this HtmlHelper htmlHelper) 
{ 
    TagBuilder tagBuilder = new TagBuilder("label"); 
    HttpResponseBase response = htmlHelper.ViewContext.HttpContext.Response; 
    response.Write(tagBuilder.ToString(TagRenderMode.StartTag)); 
    return new Label(response); 
} 

Le Étiquette implémente simplement l'interface IDisposable pour permettre la fermeture de l'étiquette:

protected virtual void Dispose(bool disposing) 
{ 
    if (!_disposed) 
    { 
     _disposed = true; 
     _httpResponse.Write("</label>"); 
    } 
} 

Utilisation ressemble à ceci:

@using (Html.BeginLabel()) 
{ 
    @Html.TextBoxFor(f => f.FirstName) 
    @Html.ValidationMessageFor(f => f.FirstName) 
} 

On dirait que je me manque quelque chose comme les étiquettes sont toujours rendues en haut du HTML et bien que cela soit évident pour moi parce que j'écris à la réponse, je ne peux pas voir comment le natif Begin Form() réalise ceci. Quelqu'un peut-il nous éclairer à ce sujet?

+0

On dirait que cela est couvert dans http://stackoverflow.com/questions/2435898/create-extension- method-to-produce-open-closing-tags-like-html-beginform –

+0

On dirait qu'il y a énormément de travail pour un si petit bénéfice. De plus, je ne suis pas sûr de ce que vous obtenez. une étiquette sans texte? En outre, je ne suis pas sûr que vous voulez le message de validation à l'intérieur de l'étiquette, soit sémantiquement parlant. –

Répondre

2
public class MvcLabel : IDisposable 
{ 
    // Fields 
    private bool _disposed; 
    private readonly TextWriter _writer; 

    public MvcLabel(ViewContext viewContext) 
    { 
     if (viewContext == null) 
     { 
      throw new ArgumentNullException("viewContext"); 
     } 
     this._writer = viewContext.Writer; 
    } 

    public void Dispose() 
    { 
     this.Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this._disposed) 
     { 
      this._disposed = true; 
      this._writer.Write("</label>"); 
     } 
    } 

    public void EndLabel() 
    { 
     this.Dispose(true); 
    } 
} 

et

public static class HtmlHelperExtension 
{ 
    // Methods 
    public static MvcLabel BeginLabel(this HtmlHelper html, string expression) 
    { 
     return html.BeginLabel(expression, null); 
    } 

    public static MvcLabel BeginLabel(this HtmlHelper html, string expression, string labelText) 
    { 
     return LabelHelper(html, ModelMetadata.FromStringExpression(expression, html.ViewData), expression, labelText); 
    } 

    public static MvcLabel BeginLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) 
    { 
     return html.BeginLabelFor<TModel, TValue>(expression, null); 
    } 

    public static MvcLabel BeginLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText) 
    { 
     return LabelHelper(html, ModelMetadata.FromLambdaExpression<TModel, TValue>(expression, html.ViewData), ExpressionHelper.GetExpressionText(expression), labelText); 
    } 

    public static MvcLabel BeginLabelForModel(this HtmlHelper html) 
    { 
     return html.BeginLabelForModel(null); 
    } 

    public static MvcLabel BeginLabelForModel(this HtmlHelper html, string labelText) 
    { 
     return LabelHelper(html, html.ViewData.ModelMetadata, string.Empty, labelText); 
    } 

    public static void EndLabel(this HtmlHelper htmlHelper) 
    { 
     htmlHelper.ViewContext.Writer.Write("</label>"); 
    } 

    internal static MvcLabel LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string labelText = null) 
    { 
     string str = labelText ?? (metadata.DisplayName ?? (metadata.PropertyName ?? htmlFieldName.Split(new char[] { '.' }).Last<string>())); 

     TagBuilder tagBuilder = new TagBuilder("label"); 
     tagBuilder.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName))); 

     html.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); 

     if (!string.IsNullOrEmpty(str)) 
     { 
      tagBuilder = new TagBuilder("span"); 
      tagBuilder.SetInnerText(str); 
      html.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.Normal)); 
     } 

     return new MvcLabel(html.ViewContext); 
    } 
} 

espoir que je peux aider les autres ...

+0

Cela me déroute, l'auteur veut utiliser la possibilité pour l'étiquette d'étiquette de contenir l'élément, qui n'utilise pas l'attribut "pour". Je ne suis pas sûr pourquoi vous mettez des travées là non plus. –

+0

ouais ce n'est pas tout à fait raison mais ne prendrait pas beaucoup de changements pour avoir raison. – DanH

+0

Également je me demande pourquoi les gens utilisent le modèle d'élimination en 2 phases sans ressources non managées. C'est comme ça dans le code MS aussi. C'est comme un mythe toujours perpétué! – DanH