Customizing the MVC Form

MVC has a set of wrappers for generating forms, which is illustrated using the following in C# Razor:

using Html.BeginForm()
{
  @* Form content *@
}

Under the scenes, Html.BeginForm renders a tag for the current controller/action (or custom ones if the parameters are supplied). It does more than that though; it works with a FormContext and generates a unique ID for the form. Being that the Microsoft way is to internalize a lot of their components, it makes it difficult to customize.

It’s actually pretty easy to customize the MVC form using a wrapper. There are several good reasons for doing so. The first reason is standardization. Most forms provide some common header or footer content around their forms to improve the appearance, or to follow a specific CSS framework. The form could also output a ValidationSummary at the top, thus saving the developers from having to write it. I did this similarly with the Anti-forgery tokens so that every form was protected.

The first step to doing so is create a form class:

public class CustomForm : MVCForm
{
    private MvcForm _form = null;
    private ViewContext _viewContext = null;
    private bool _disposed = false;

    public CustomForm(MvcForm form, ViewContext viewContext) : base(viewContext)
    {
       _form = form;
       _viewContext = viewContext;
    }
}

The constructor of the form wraps the MVC form, taking it as the first constructor parameter, and the ViewContext which the form expects. To render the end of the form, override the Dispose method, and do the following:

protected override void Dispose(bool disposing)
{
    if (_disposed)
      return;

     //Wrap up any customization HTML here

     if (_form != null) {
       _form.Dispose();
     }
    _disposed = true;
}

On disposing of the form, this renders the end of the form (the end tag, and wrap up some of the internal form stuff).

The initial rendering of the form happens in the BeginForm extension method, so we need something similar:

[Extension]
public static CustomForm BeginCustomForm(this HtmlHelper html, ..)
{
   var form = html.BeginForm(..); //set parameters to form, let the original form do the work or rendering
   html.ViewContext.Writer.Write(html.AntiForgeryToken());
   html.ViewContext.Writer.Write("I'm within the form, write any customization text here");
}

Here the html.BeginForm extension renders the tag with any attributes provided. It also writes the anti-forgery token and a custom message.

And that’s all it takes to standardize your applications forms and minimize the actual amount of code you have to write! It can amount to a time savings over the long run of an application.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s