实现.net mvc BeginLabel就像BeginForm response.write一样

时间:2011-08-01 11:21:03

标签: asp.net-mvc label response.write

我需要为Mvc推送自己的BeginLabel助手。我检查/从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 个答案:

答案 0 :(得分:3)

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

希望我能帮助别人......