Page Validation for Large Forms in MVC

Home » ASP.NET MVC » C# » Page Validation for Large Forms in MVC
ASP.NET MVC Logo

Summary

A recent application I worked on had a large form that consisted of over 10 tabs worth of information – over 100 fields in total. This information came from another source (a tablet), and needed to be fully validated before being processed further. I searched around on the web looking for an example of how to most efficiently do this, and didn’t find one. Sure the standard MVC unobtrusive validation could be used, but I wanted to improve on it, so that:

  1. The user would see validation errors when entering the page.
  2. They did not have to fill in every single field with a validation error in order to save, because the information may not be known at the time.

One very important angle is that there has to be two types of validation. The type of validation that must always be validated is for example entering a string into a numeric field, or a characters into a date field. For this, I used standard MVC unobtrusive validation and data annotations.

The only problem I can find with my solution is that client side validation has to be turned off. Its a total server side solution at present. I would be interested in receiving any feedback particularly in this regard as obviously client side validation is a good thing. For me in the app I was working on however, which is an intranet app with a couple of users, turning off client side validation is not a big deal. It might be if the system had hundreds of users.

How it Works

The core MVC validation was used to validate things like data types, required fields, max lengths, in fact anything that if not validated would cause an error when trying to save. I also looked at IValidatableObject. The problem I had was that the validation would do two passes through, it would look at things like Required fields and MaxLengths, then if everything checked out ok would then run the Validate() method on IValidatableObject as well as. I wanted to split this out so I had two tiers of validation – validation that would just come up on screen and not stop the save, and validation that stopped the save.

Getting Started

To start on a tangent, getting all those fields on one page was easy enough – as I was using Bootstrap 3 framework, Bootstrap tabs was a reasonably obvious solution.

I created the model classes, and put the necessary data annotations on these classes to prevent problems with the save, e.g. Max lengths, data types, and required just for fields that were defined as NOT NULL in the database.

The Second Level of Validation

I wanted to use as much of the MVC framework as possible, so the next step was to create an interface, which I called IBcValidatableObject, with one method:

The implementation of this interface in the model is exactly the same as for IValidatableObject, its just that it has to be manually called, it isn’t called automatically by MVC. An example follows:

The next step is to alter the controller to do the validation when entering the edit page. In this circumstance, ALL the validation needs to be executed, so all errors are displayed on the page:

AddErrorsToModelState was a function I created to translate the output from the validate method to the page, as follows:

When the user pressed Save, the standard MVC validation has to take place to ensure the record can be saved, then additional validation takes place to ensure that the correct errors are displayed on the page:

Thats it! The only thing missing from this example is the code I used in the service to do the different validation I needed:

  1. Full Validation
  2. Additional Validation

Full Validation

Additional Validation

N.B. In this example for clarity, I have removed the code that handles multiple sections in my model.

As always, any and all feedback welcome.

About Phil

I have been working as a software developer since 1983. This blog could have been called "From Fortran 77, C and Cobol to C# in 20 (not so) easy years", but it doesn't sound quite right somehow. Besides I'm talking about what's happened since 2003, not before!

Leave a Reply

Your email address will not be published.


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">




Top Posts & Pages

Categories

Recent Posts

Recent Comments

Archives

Blogroll

  • Mike Cohn's Blog
  • Scott Hanselman's Blog
- mike@mountaingoatsoftware.com

The iterative and incremental nature of agile makes an agile approach seemingly less compatible with [...]

- mike@mountaingoatsoftware.com

Velocity can be great for predicting how much a team can deliver in a given period. But it needs to [...]

- mike@mountaingoatsoftware.com

Succeeding with agile isn’t just about knowing where to start, it’s about knowing where to go next—w [...]

- mike@mountaingoatsoftware.com

Here’s what to do when facing a complex user story that cannot be split but is too large for one spr [...]

- mike@mountaingoatsoftware.com

A lot of organizations claim to be agile. Here’s a quick way to see if they really are. [...]

- Scott Hanselman

ASP.NET Core 2.2 is out and released and upgrading my podcast site was very easy. Once I had it upda [...]

- Scott Hanselman

Well crap. I was typing really fast and got a squiggly, so I right-clicked on it and rather than sel [...]

- Scott Hanselman

Buckle up friends! Microsoft is open sourcing WPF, Windows Forms (winforms), and WinUI, so the three [...]

- Scott Hanselman

Naming things is hard. I've talked before about the term "evangelism" and my dislike [...]

- Scott Hanselman

Hey friends! This is my FIFTH year doing a list of Great STEM Christmas Toys for Kids! Can you belie [...]

Meta