3

I try to create some Html Helpers which will have an opening tag and closing tag which will include other contents like the Html.BeginForm does. For example in Razor we can use the Html.BeginForm helper which has the following syntax:

    @using (Html.BeginForm())
    {
    }

This code will include the contents of curly brackets within a and . The only way that I solved opening and closing a tag with contents is by using two html helpers. I define two html helpers:

    public static MvcHtmlString StartForm(this System.Web.Mvc.HtmlHelper helper)
    {
        return new MvcHtmlString("<form>");
    }
    public static MvcHtmlString EndForm(this System.Web.Mvc.HtmlHelper helper)
    {
        return new MvcHtmlString("</form>");
    }

Then I use the helpers using the following example:

    @Html.StartForm()
    contents
    @Html.EndForm()

But I would like to be able to make one html helper which will have the following format in the view:

    @using (Html.MyForm())
    {
            <text>contents</text>
    }

Can someone help me with this problem because I do not know even how to search it.

4
  • Take a look here: stackoverflow.com/questions/8356506/… and here: stackoverflow.com/questions/4713931/… Commented Apr 19, 2014 at 23:49
  • These articles explain how to use the Html.BeginForm. I want to create my own html helper to act like the Html.BeginForm. I would like to have an Html Helper which will get somehow the contents that we add between the curly brackets so that I will be able to send it back after processing it. Commented Apr 19, 2014 at 23:55
  • You can see exactly how it's implemented by looking at the source code here. But for the effort in this case I would just forget about using the helper and writing out the form tags directly. Commented Apr 20, 2014 at 0:08
  • Agree with Jasen, writing out the form tag is easier and effortless. However, if you wish, you can implement a class like the way the MvcForm is done. Commented Apr 20, 2014 at 1:05

1 Answer 1

7

You can define a class just like the way the MvcForm is implemented. The class below allows you to create a tag which contains other elements.

public class MvcTag : IDisposable
{
    private string _tag;
    private bool _disposed;
    private readonly FormContext _originalFormContext;
    private readonly ViewContext _viewContext;
    private readonly TextWriter _writer;

    public MvcTag(ViewContext viewContext, string tag)
    {
        if (viewContext == null)
        {
            throw new ArgumentNullException("viewContext");
        }

        _viewContext = viewContext;
        _writer = viewContext.Writer;
        _originalFormContext = viewContext.FormContext;
        viewContext.FormContext = new FormContext();
        _tag = tag;
        Begin(); // opening the tag
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public void Begin()
    {
        _writer.Write("<" + _tag + ">");
    }

    private void End()
    {
        _writer.Write("</" + _tag + ">");
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            _disposed = true;
            End(); // Closing the tag

            if (_viewContext != null)
            {
                _viewContext.OutputClientValidation();
                _viewContext.FormContext = _originalFormContext;
            }
        }
    }

    public void EndForm()
    {
        Dispose(true);
    }
}

To make use of this MvcTag in the way the MvcForm is used, we have to define an extension

public static class HtmlHelperExtensions
{
    public static MvcTag BeginTag(this HtmlHelper htmlHelper, string tag)
    {
        return new MvcTag(htmlHelper.ViewContext, tag);
    }
}

And that's it. Now you can use it as:

@using(Html.BeginTag("div")) @* This creates a <div>, alternatively, you can create any tag with it ("span", "p" etc.) *@
{ 
    <p>Contents</p>
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you vbn very much. This is what I wanted.
I'd highly recommend using TagBuilder instead of manually creating tags. MVC has used this to create tags for a least since MVC 2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.