问题
I'm writing my first asp.net mvc application and I have a question about custom Html helpers:
For making a form, you can use:
<% using (Html.BeginForm()) {%>
*stuff here*
<% } %>
I would like to do something similar with a custom HTML helper. In other words, I want to change:
Html.BeginTr();
Html.Td(day.Description);
Html.EndTr();
into:
using Html.BeginTr(){
Html.Td(day.Description);
}
Is this possible?
回答1:
Here is a possible reusable implementation in 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()
);
}
}
In this case, BeginTr
and EndTr
directly write in the response stream. If you use extension methods that return a string, you'll have to output them using :
htmlHelper.ViewContext.HttpContext.Response.Write(s)
回答2:
I tried following the advice given here in MVC3, but I ran into trouble using:
htmlHelper.ViewContext.HttpContext.Response.Write(...);
When I used this code, my helper was writing into the Response stream BEFORE my Layout was rendered. This didn't work well.
Instead I used this:
htmlHelper.ViewContext.Writer.Write(...);
回答3:
If you look at the source for the ASP.NET MVC (available on Codeplex), you'll see the implementation of the BeginForm eventually calls down to the following code:
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);
}
The MvcForm class implements IDisposable, in it's dispose method is writes the </form> to the response.
So, what you'd need to do is write the tags you want out in the helper method and return an object that implements IDisposable...in it's dispose method close the tag off.
来源:https://stackoverflow.com/questions/676746/custom-html-helpers-create-helper-with-using-statement-support