我正在编写我的第一个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
直接在响应流写入.如果使用返回字符串的扩展方法,则必须使用以下命令输出它们:
htmlHelper.ViewContext.HttpContext.Response.Write(s)
我尝试按照MVC3中给出的建议,但我遇到了麻烦:
htmlHelper.ViewContext.HttpContext.Response.Write(...);
当我使用这段代码时,我的助手在渲染我的布局之前写入了响应流.这不行.
相反,我使用了这个:
htmlHelper.ViewContext.Writer.Write(...);
如果您查看ASP.NET MVC的源代码(可在Codeplex上找到),您将看到BeginForm的实现最终调用以下代码:
static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionaryhtmlAttributes) { TagBuilder builder = new TagBuilder("form"); builder.MergeAttributes (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方法是将 form>写入响应.
所以,你需要做的是在helper方法中编写你想要的标签并返回一个实现IDisposable的对象...在它的dispose方法中关闭标签.