【问题标题】:Custom html helpers: Create helper with "using" statement support自定义 html 助手:使用“使用”语句支持创建助手
【发布时间】:2009-03-24 10:04:21
【问题描述】:

我正在编写我的第一个 asp.net mvc 应用程序,我有一个关于自定义 Html 帮助程序的问题:

要制作表格,您可以使用:

<% using (Html.BeginForm()) {%>
   *stuff here*
<% } %>

我想用自定义 HTML 帮助器做类似的事情。 换句话说,我想改变:

Html.BeginTr();
Html.Td(day.Description);
Html.EndTr();

进入:

using Html.BeginTr(){
    Html.Td(day.Description);
}

这可能吗?

【问题讨论】:

    标签: .net asp.net-mvc html-helper


    【解决方案1】:

    这是一个在 c# 中可能的可重用实现:

    class DisposableHelper : IDisposable
    {
        private Action end;
    
        // When the object is created, write "begin" function
        public DisposableHelper(Action begin, Action end)
        {
            this.end = end;
            begin();
        }
    
        // When the object is disposed (end of using block), write "end" function
        public void Dispose()
        {
            end();
        }
    }
    
    public static class DisposableExtensions
    {
        public static IDisposable DisposableTr(this HtmlHelper htmlHelper)
        {
            return new DisposableHelper(
                () => htmlHelper.BeginTr(),
                () => htmlHelper.EndTr()
            );
        }
    }
    

    在这种情况下,BeginTrEndTr 直接写入响应流。如果您使用返回字符串的扩展方法,则必须使用 :

    输出它们
    htmlHelper.ViewContext.HttpContext.Response.Write(s)
    

    【讨论】:

    • pweh.. 我认为这很容易.. 感谢您的努力。
    • 这只是一个快速而肮脏的实现。 “开始”委托可以直接在您的扩展方法中调用,并且 DisposableHelper 类可重用于其他扩展
    • 不知道这有什么不容易的——这确实是一个非常优雅的解决方案。
    • @ybo 非常感谢。我将它用于Ajax.ActionLink 以支持 htmlcontent,它现在提供非常干净的代码。
    【解决方案2】:

    我尝试按照 MVC3 中给出的建议进行操作,但在使用时遇到了麻烦:

    htmlHelper.ViewContext.HttpContext.Response.Write(...);
    

    当我使用此代码时,我的助手在我的布局呈现之前写入响应流。这效果不好。

    相反,我使用了这个:

    htmlHelper.ViewContext.Writer.Write(...);
    

    【讨论】:

    • 非常感谢。为我节省了大量时间。
    • 在 MVC 3 中为我工作,使用原始代码在 html 正文下方写出 html 帮助程序内容。这解决了它。
    【解决方案3】:

    如果您查看 ASP.NET MVC 的源代码(可在 Codeplex 上获得),您会看到 BeginForm 的实现最终会调用以下代码:

    static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes)
    {
        TagBuilder builder = new TagBuilder("form");
        builder.MergeAttributes<string, object>(htmlAttributes);
        builder.MergeAttribute("action", formAction);
        builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
        htmlHelper.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag));
    
        return new MvcForm(htmlHelper.ViewContext.HttpContext.Response);
    }
    

    MvcForm类实现了IDisposable,在它的dispose方法中是写到响应中。

    所以,你需要做的是在辅助方法中写出你想要的标签,并返回一个实现 IDisposable 的对象......在它的 dispose 方法中关闭标签。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 1970-01-01
      • 2015-10-20
      • 2011-03-09
      • 2014-03-07
      • 1970-01-01
      • 2014-12-04
      相关资源
      最近更新 更多