Share via


Duplicate validation error messages with DataAnnotations

Question

Thursday, October 29, 2009 5:33 PM

I am using MVC 2 preview 1 with System.ComponentModel.DataAnnotations on my model classes.  I am getting two error messages when certain fields are left out.  I think this has to do with the default auto binder error messages being displayed along with the DataAnnotations error messages.  In the below example I receive two error messages when the RoleId field has no value.  If I select a value for RoleId the form submits perfectly.  Hopefully someone can explain what is going on.  Screen shot and code below.

Screen Shot

Model

using System.ComponentModel.DataAnnotations;
namespace ClaimAudit.Mvc.Models
{
    public class UserModel
    {
        public virtual int Id {get; set;}
        [StringLength(35), Required]
        public virtual string FirstName {get; set;}
        [StringLength(35), Required]
        public virtual string LastName {get; set;}
        [Required]
        public virtual int RoleId {get; set;}
        [StringLength(35), Required]
        public virtual string Username {get; set;}

        public UserModel() {}
    }
}

**Controller Actions
**

        public ActionResult Add() {
             this.prepareUserForm();
             return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Add([Bind(Exclude="Id")]UserModel userModel) {
            
            if (!ModelState.IsValid) {
                this.prepareUserForm();
                return View();
            }

            User user = EntityModelHelper.CreateEntityFromModel(userModel);
            userDataAccess.Save(user)

            //add confirmation message
            this.AddUserMessage("User saved successfully");

            return RedirectToAction("List");
        }

View

 <% using (Html.BeginForm()) {%>
        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="FirstName">FirstName:</label>
                <%= Html.TextBox("FirstName") %>
                <%= Html.ValidationMessage("FirstName", "*") %>
            </p>
            <p>
                <label for="LastName">LastName:</label>
                <%= Html.TextBox("LastName") %>
                <%= Html.ValidationMessage("LastName", "*") %>
            </p>
            <p>
                <label for="Username">Username:</label>
                <%= Html.TextBox("Username") %>
                <%= Html.ValidationMessage("Username", "*") %>
            </p>
            <p>
                <label for="Model">Role:</label>
                <%= Html.DropDownList("RoleId", "* Select One *") %>
                <%= Html.ValidationMessage("RoleId", "*") %>
            </p>            
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>
 <% } %>

All replies (2)

Monday, November 2, 2009 2:32 AM

Hi,

Based on my experience, one message is generated by DataAnnotations and the other is created by yourself.

So you can check the method prepareUserForm() to see whether you add another error message to the modelstate.

If it is, you can do as the following code.

 if (ModelState["DisplayOrder"].Errors.Count != 0)
                {
                    ModelState.Remove("DisplayOrder");
                    ModelState.AddModelError("DisplayOrder", "The display order must be positive integer");
                }

Monday, January 25, 2010 6:29 PM

The actual answer to this is that somwhere in the auto binding code an exception is being thrown because "" can not be binded to int.  Long story short I changed all my int's, DateTime's, float's, to their Nullable<T> versions and it works fine.  I no longer see the "A value is required" message.

using System;
using ClaimAudit.Entity;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel;

namespace ClaimAudit.Mvc.Models
{
    public class UserModel
    {

        public virtual int Id {get; set;}

        [StringLength(35), Required]
        [DisplayName("First Name")]
        public virtual string FirstName {get; set;}

        [StringLength(35), Required]
        [DisplayName("Last Name")]
        public virtual string LastName {get; set;}

        [Required]
        public virtual int? RoleId {get; set;}

        [StringLength(35), Required]
        public virtual string Username {get; set;}

        [DisplayName("Start Date")]
        public DateTime? SecondaryStartDate { get; set; }

        [DisplayName("End Date")]
        public DateTime? SecondaryEndDate { get; set; }
  
        
        public UserModel() {}


    }
}