views:

533

answers:

2

I'm using MVC 2 with some Models from a LinqToSql project that I built. I see that when I post back to a Controller Action after editing a form that has a DateTime field from the Model, the MVC Html.ValidationMessageFor() helper will nicely display an error beside the Date text box.

This seems to happen automatically when the you test ModelState.IsValid() in the Controller Action, as if the MVC model binding automatically knows that the DateTime field cannot be empty. My question is... I have some other string fields in these LinqToSql generated classes that are Not-Nullable (marked as Not Nullable in Sql Server which passes through to the LinqToSql generated classes), so why doesn't Mr. MVC pick up on those as well and display a "Required" message in the ValidationMessageFor() placeholders I have added for those fields, like it does for the DateTime field?

Sure, I have successfully added the MetadataType(typeof< t >) buddy classes to cover these non-nullable string fields, but it sure does seem redundant to add all this metadata in buddy classes when the LinqToSql generated classes already contain enough info that MVC could sniff out, like it does for the DateTime. If MVC validation works with DateTime automatically, why not these Not-nullable fields too?

A: 

Since you mention ValidationMessageFor(), I assume that you have this field on the form (there was a change in later builds of MVC 2 that "required" in model isn't really required if the field isn't in the View).

The other reason that I noticed is that Mr MVC might notice that there is an error; but the message is suppressed either by DataAnnotation settings, or maybe even by ValidationMessageFor() itself. I don't remember the details now, but I was puzzled why there is no message, and found out that it's just that the validation message itself is empty.

The easiest way to exclude such possibility is to break in the debugger, and see if the ModelState.IsValid is true. If false, then obviously Mr MVC did pick up... If true - I've never seen such thing (field defined as required, but no error detected); but I worked predominantly with EF. While I would expect that LinqToSql act the same - I don't have first-hand experience

Felix
I did break it and trace though a post action... When the string fields are empty, ModelState.IsValid is true, so Mr. MVC is *not* seeing any validation errors. I do, however, get DAL error when I try to Save() the model, since SQL Server knows the fields cannot be null, and I have to deal with that. Once I hook up the buddy classes, MVC sees the error, and I never even attempt a Save() hit to the DAL.As stated in the question, MVC sees an empty DateTime right off the bat, and it is *not* included in a buddy class or anywhere else.
MattSlay
By the way, Yes, I do have input fields on the form for each of the properties on the model.
MattSlay
Completely grasping at a straw... is it possible that Model defines it as *not* required field (say, it has a default value, but you pass a NULL, and assigning default doesn't kick in). When you say *empty* string, I assume you mean NULL, not "". And if this field is not-nullable in the DB, with "" as default value, but nullable in the model - you could have what I described aboveAs I said, I've never seen this in EF; so if this doesn't help - I give up :(
Felix
Hmmm... You're sugeesting that the form is posting back an empty string, which passes model validation, so no validation error ocurrs in MVC. Let's say that is true (I can check by running through the debugger later)... Well, then the UpdateModel(dalObject) method should be passing that empty string into the DAL object (but I don't think it is) becuase then I call Save() on my DAL class and *that* is where the DAL class gets notified that the DB field cannot be null. However, you've give me something to study.
MattSlay
Actually, I am suggesting that model does not enforce non-nullability, and go into some speculation as to why. If form were to pass empty string, then you are right - you wouldn't have problems with DAL, either.
Felix
A: 

AFAIK all value typed action parameters are automatically required and validated, whereas reference type action parameters are not. they are validated agains some validation provider ie. DataAnnotations.

Robert Koritnik
Matches an answer I received on the Asp.Net MVC forum:"The binder knows only about static type information. Since DateTime is a non-nullable value type, the binder can detect that null incoming values have absolutely no chance of being bound correctly.Since String is a reference type, it can accept null values, so the binder attempts to setthese properties to null. It has no way of knowing from the static type information itself that the backing column in the database is non-nullable."
MattSlay