09 January 2012 ASP.NET MVC, Validation Robert Muehsig

Um Daten in einen MVC Controller zu bekommen ist das Modelbinding von MVCeigentlich recht clever. Allerdings ist es etwas kompliziert, die Fehlermeldung zu setzen, wenn das Binding nicht geklappt hat.

Bsp:

    public class RegisterModel
    {
		...

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string Email { get; set; }

        [Required]
        [Display(Name = "Age")]
        public int Age { get; set; }

		...
    }

 

Dies ist das Standardmodell für die Registrierung in der ASP.NET MVC Projektvorlage. Ich habe ein Property “Age” vom Typ “int” hinzugefügt. Auch im View muss die mit angegeben werden:

            ...
			<div class="editor-label">
                @Html.LabelFor(m => m.Age)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.Age)
                @Html.ValidationMessageFor(m => m.Age)
            </div>
			...

 

Problem: Was passiert, wenn nun der Nutzer anstatt einer Zahl Buchstaben eingibt?

Solange die ClientValidation an ist, ist auch alles gut:

image

Wenn sie allerdings aus ist kommt im Standardfall diese Fehlermeldung:

image

Die Fehlermeldung “The value ‘Test’ is not valid for Age.” wird direkt in den ModelState geschrieben:

image

Leider lässt sich diese Meldung nur recht kompliziert ändern – dabei werden auch jegliche Sprachen ignoriert. Das sieht natürlich auf einer deutschen Seite nicht so schön aus.

Fix: Ressourcen Datei erstellen

Unter App_GlobalResources muss man eine Resource-Datei erstellen und ein Eintrag “PropertyValueInvalid” einfügen und dann dahinter den dazugehörigen Text:

image

In der Global.asax die Resource-Datei verlinken:

		protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            DefaultModelBinder.ResourceClassKey = "Errors"; <-- lookup in Errors.resx

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

 

Ergebnis:

image

Hintergrund:

Jegliche Validierunglogik kann nicht ausgeführt werden, da das Framework das Property nicht binden kann. Interessanterweise ist das Verhalten des Frameworks etwas anders wenn man eine zu große Zahl dem Int zuweisen möchte. In diesem Fall kommt im ModelState eine Exception an, welche man abfangen kann. Auch die Validierung kann da greifen. Das Problem trat bei mir auch nur im Zusammenhang von String-Eingaben auf.


Written by Robert Muehsig

Software Developer - from Saxony, Germany - working on primedocs.io. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de