views:

1357

answers:

2

There appears to be something of a hole in the way DataAnnotations works in that a user entering in some text into a field that will go into an int will never reach the DataAnnotations code. It kicks off a model binding error and displays the error to the user "The value 'a' is not valid for the XXXX field."

Anyway, it's all very nice that it automatically handles this situation, but I actually want to display an error message indicating the problem eg. "The value 'a' is not numeric. Please enter in a numeric value for the XXXX field".

I have tried the solutions set out http://stackoverflow.com/questions/1538873/how-to-replace-the-default-modelstate-error-message-in-asp-net-mvc-2 and http://stackoverflow.com/questions/646270/asp-net-mvc-custom-validation-message-for-value-types/1374653#1374653, but I can't get them to work.

It appears that my resource file is not being read at all, since here (http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultmodelbinder.resourceclasskey.aspx) it states "If the property is set to an invalid class key (such as a resource file that does not exist), MVC throws an exception." and even if I change the line to DefaultModelBinder.ResourceClassKey = "asdfasdhfk" there is no exception.

Anyone have any ideas?

EDIT: Here is some code. All of it is working minus my Messages.resx file's messages are not being used. The code for Messages.resx is auto generated so I won't include it.

So entering "a" into ProcessOrder results in a generic message rather than what I have entered into Messages.resx for PropertyValueInvalid (and InvalidPropertyValue for good measure).

Application_Start method

protected void Application_Start()
{            
    RegisterRoutes(RouteTable.Routes);
    ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder(); //set dataanooations to be used
    DefaultModelBinder.ResourceClassKey = "Messages"; //set data annotations to look in messages.resx for the default messages
    ValidationExtensions.ResourceClassKey = "Messages";
}

Entity Class

[MetadataType(typeof(GLMetaData))]
public partial class GL
{

}



public class GLMetaData
{
    public int TransRefId { get; set; }

    [DisplayName("Process Order")]
    public int? ProcessOrder { get; set; }

    [DisplayName("Trans Type")]
    [StringLength(50)]
    public string TransType { get; set; }

    [StringLength(100)]
    public string Description { get; set; }

    [DisplayName("GL Code")]
    [StringLength(20)]
    public string GLCode { get; set; }

    [DisplayName("Agents Credit No")]
    [StringLength(50)]
    public string AgentsCreditNo { get; set; }

    [Required]
    public bool Active { get; set; }
}

Controller Action:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(GL glToBeUpdated)
    {
        try
        {
            if (!ModelState.IsValid)
                return View(glToBeUpdated);

            //set auto properties
            glToBeUpdated.UpdateDate = DateTime.Now;
            glToBeUpdated.UpdateUser = this.CurrentUser;

            glDataLayer.update(glToBeUpdated);

            glDataLayer.submitChanges();

            return RedirectToAction("Index");
        }
        catch
        {
            glDataLayer.abortChanges();

            throw;
        }
    }
A: 

What I did to combat a similar issue was to clear the model state, validate against ModelState["XXXX"].Value.AttemptedValue instead of against the nulled value caused by an trying to put an invalid value into the Model's property, populating the error messages and resetting the Model values.

That way I can have the error messages I want and if necessary offer more than one ("a value is required" or "the value must be numeric").

mark123
Interesting, however the DataAnnotations validation is not reached at all so I can't use this method. I decided to just use the jquery alphanumeric plugin to stop non-numeric data from being entered. You can still get past this validation in some cases, but overall the solution is good enough.
Alistair
A: 

look this link:

http://stackoverflow.com/questions/1538873/how-to-replace-the-default-modelstate-error-message-in-asp-net-mvc-2/2115065#2115065

C.T.
Tried that way, but it wasn't working.
Alistair
try this link:http://stackoverflow.com/questions/1538873/how-to-replace-the-default-modelstate-error-message-in-asp-net-mvc-2/1540874#1540874and change InvalidPropertyValue to PropertyValueInvalid if you are using asp.net mvc 2 rc.
C.T.