Custom html helpers: Create helper with “using” statement support

流过昼夜 提交于 2020-01-19 04:32:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!