Mark Gilbert's Blog

Science and technology, served light and fluffy.

Making sense on many levels – ASP.NET MVC 2 and Model-Level Error Reporting

In the previous episode of “Mark and the Chartreuse-Field Project”, Mark was working to get site-wide error reporting up and running.  Today, Mark tackles model-level error reporting.  Let’s tune in and see how he’s doing.

***

Early on in this project I learned how to associate a custom error message with a specific form field:

ViewData.ModelState.AddModelError("MyField", "My custom error message here")

That allowed the out-of-the-box validation messaging to highlight the offending field and display the message right next to it:

<%=Html.ValidationMessageFor(Function(model) model.MyField)%>

However, today I ran into a situation where I needed to be able to display a custom message that applied to the entire page, not a specific field.  There was a validation summary control at the top of the page already:

<%= Html.ValidationSummary(True) %>

My first thought was to associate the custom message with that control so it would appear there.  Following the pattern to associate a message with a specific field, my first attempt at code-roulette looked like this:

ViewData.ModelState.AddModelError("", "My custom error message here")

I then threw a dummy exception in the middle of one of my controller actions to force an error to appear.  No dice – the error was simply swallowed by the page.  I did some searching and came across a post (http://stackoverflow.com/questions/4017827/manually-adding-text-to-html-validationsummary) that mentioned using an asterisk as the field name to get the message to show up in the validation summary:

ViewData.ModelState.AddModelError("*", "My custom error message here")

Still no dice.  Ok, time to back up a minute.  Was my custom error even making it into the ModelState object?  I put a breakpoint on the line immediately after AddModelError, and inspected the ViewData.ModelState.Keys property:

(0): "id"
(1): "CurrentEvent.Title"

(17): "*"

So, if the error is getting added to the ModelState correctly, then why isn’t it showing up?  The answer came in two parts.  First, I was passing a “True” to Html.ValidationSummary.  This was configuring the control to not display messages that were tied to a field (the actual parameter name here is “excludePropertyErrors”).  My asterisk was being treated like another field name – one that didn’t match a field-level validation control – and was therefore being excluded by the validation summary control.  Second, a post from the ASP.NET forums (http://forums.asp.net/p/1628537/4193163.aspx) suggested that displaying model-level errors were not possible in MVC 2, and apparently were in MVC 3.  Upgrading wasn’t an option for me, so I needed to find another way.

What if I were to create a new model property called ErrorMessage, and then associate the custom messages with THAT field?  Then, I would just need to add a validation control for that field to my view.  I added the property, “ErrorMessage”, to my model and modified my AddModelError call like so:

ViewData.ModelState.AddModelError("ErrorMessage", "My custom error message here")

Then I added a Html.ValidationMessageFor control to my view, and tied it to this new property:

<%=Html.ValidationMessageFor(Function(model) model.ErrorMessage)%>

And voila!  Model-level errors in MVC 2!

Advertisements

March 2, 2011 - Posted by | ASP.NET MVC, Visual Studio/.NET

4 Comments

  1. To solve this problem you need to place
    into base View (not in EditorTemplates)

    Comment by mirdin | April 18, 2011

  2. By the way Mark,

    I really liked to read your About page: https://markegilbert.wordpress.com/about/ 😀

    Your last phrase makes a lot of sense…

    Comment by Leniel Macaferi | April 25, 2011

  3. Hi Mark,

    Interesting read. 🙂

    I was facing the same problem but then I found this link in Google Books (Pro ASP.NET MVC 2 Framework by Steven Sanderson): http://goo.gl/32j4j

    I tried what is described there passing an empty string as key (string.Empty) and it did the job.

    Chech my StackOverflow question and answer: http://stackoverflow.com/questions/5697487/whats-the-best-way-to-localize-non-data-annotation-errors-with-asp-net-mvc-3/5766290#5766290

    Hope it helps,

    Leniel

    Comment by Leniel Macaferi | April 25, 2011

    • @Leniel: I’m glad you got the empty string approach to work. That made the most sense to me out of the gate, but alas, it didn’t work (I still have no good reason why). I’m curious why adding a new property to your model, and then manually associating the model-level error messages to that property didn’t work for you.

      Comment by markegilbert | April 25, 2011


Sorry, the comment form is closed at this time.

%d bloggers like this: