自定义html助手:使用“使用”语句支持创build助手
我正在写我的第一个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); }
这可能吗?
这里是一个可能的可重用的实现在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() ); } }
在这种情况下, BeginTr
和EndTr
直接写入响应stream。 如果您使用返回string的扩展方法,则必须使用以下方法输出它们:
htmlHelper.ViewContext.HttpContext.Response.Write(s)
我试着按照MVC3给出的build议,但我遇到了麻烦,使用:
htmlHelper.ViewContext.HttpContext.Response.Write(...);
当我使用这个代码时,我的帮手正在写入我的布局呈现之前的响应stream。 这不好。
相反,我用这个:
htmlHelper.ViewContext.Writer.Write(...);
如果您查看ASP.NET MVC的源代码(可在Codeplex上find ),您将看到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,它的configuration方法是将</ form>写入响应。
所以,你需要做的是写你想要的标签在辅助方法中,并返回一个实现IDisposable的对象…在它的dispose方法closures标签closures。