Внедрите .net mvc BeginLabel как проблему BeginForm response.write - PullRequest
1 голос
/ 01 августа 2011

У меня есть требование накатить мой собственный помощник BeginLabel для Mvc.Я проверил / украл концепцию из источника Mvc для методов html.beginForm / ajax.beginForm.

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);
}

Метка просто реализует интерфейс IDisposable для включения закрытия метки:

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

Использование выглядит следующим образом:

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

Похоже, я что-то упускаю, так как метки всегда отображаются в верхней части HTML, и хотя это очевидно для меня, потому чтоЯ пишу в ответ, я не вижу, как нативный BeginForm () достигает этого.Кто-нибудь может пролить свет на это?

1 Ответ

3 голосов
/ 23 октября 2011
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);
    }
}

и

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);
    }
}

Надеюсь, я смогу помочь другим ...

...