Has the behaviour of the UpdateModel<T> changed in MVC 2 (RTM)? Since then I have the following problem when UpdateModel is called:
UpdateModel<T1>(record, properties);
record is typeof(Jumbo.Juist.Models.Bezorging) and properties is a string[] containing "Winkelnummer" and "OudRoutenummer".
This now fails, because a get-property is being accessed: BerekendeAankomstTijd. In the past, it didn't fail. IMHO, this validation should be skipped, because it's only a getter (and thus/also not included in the string[] of properties to update).
Is there a way to do an UpdateModel without validation of "untouched" properties?
Of course I fixed this problem by doing a check in the property getter, but I'm just annoyed that my properties are accessed with an UpdateModel call.
I believe MVC 2 has switched to model based validation. What that means is that say you have this class:
student: id, name, age, gender
and say name, age and gender are required.
If a form previously submitted only name and age but not gender, then it would have passed validation (i.e. gender wasn't posted, so it's not validated.)
In MVC 2, they've changed that so even if gender is not passed, validation will be carried out on name, age AND gender.
Perhaps this is the issue you're running into.
"If I can see further than anyone else, it is only because I am standing on the shoulders of giants."blog: www.heartysoft.com twitter: @ashic
Thanks for the link. Although it doesn't address the problem of readonly properties being checked during model validation, some user comments directed me to:
We investigated this and have concluded that the validation system is behaving as expected. Since model validation involves attempting to run validation over all properties, and since non-nullable value type properties have an implicit [Required] attribute,
we're validating this property and calling its getter in the process. We understand that this is a breaking change from V1 of the product, but it's necessary to make the new model validation system operate correctly.
You have a few options to work around this. Any one of these should work:
Change the Date property to a method instead of a property; this way it will be ignored by the MVC framework.
Change the property type to DateTime? instead of DateTime. This removes the implicit [Required] from this property.
Clear the static DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes flag. This removes the implicit [Required] from all non-nullable value type properties application-wide. We're considering adding in V3 of the product an attribute
which will signal to us "don't bind it, don't validate it, just pretend that this property doesn't exist."
-----
I don't like this change in MVC2; unfortunately there is not an easy way to get the MVC1 behaviour...
I consider it a bug that ASP.NET MVC runs [Required]-validators on value types. It is completely unneccessary and a waste of processor time since such a validation cannot fail, ever.
Well, it can fail, like in my case, when an exception is thrown, so the only reason for this check would be exactly that case.
Nevertheless, I think it should never be done on get-only properties, because they should be dependend on other (settable) properties (they could also depend on fields, of course, but in that case property validation isn't enough anyway). Therefore, validating
the set-properties and validating the model should suffice.
The DataAnnotations attributes provide for all kind of checks, but unfortunately lacks an attribute for "do not check". So, according to me, the beste would be
* run [Required]-validators on value-types when there is a set-accessor, unless marked as [DoNotValidate]
* don't run [Required]-validators on value-types when there is only a get-accessor, unless marked as [Required] explicitely.
I consider it a bug that ASP.NET MVC runs [Required]-validators on value types. It is completely unneccessary and a waste of processor time since such a validation cannot fail, ever.
This is incorrect. Subclassed types of [Required] can have side effects, so we have to run all attributes that we find.
The particular issue under discussion here is whether the framework should
implicitly add [Required] to value-type properties. This was done so that client-side validation works properly. We probably should have been smarter about saying that the implicit [Required] should be added only during client validation, not during server
validation (and there's a work item to do precisely this in MVC 3). The switch mentioned earlier in this thread will toggle the implicit attribute for both client + server validation.
If the planned change goes in for MVC 3, then the only property getters called by the server-side validation framework will be those to which any
explicit attributes ([Required] and otherwise) are applied. It seems like this behavior will satisfy everybody.
Marked as answer by ricka6 on May 18, 2010 11:13 PM
I consider it a bug that ASP.NET MVC runs [Required]-validators on value types. It is completely unneccessary and a waste of processor time since such a validation cannot fail, ever.
This is incorrect. Subclassed types of [Required] can have side effects, so we have to run all attributes that we find.
If a value is of a value type then by definition it will have a value. Thus, [Required] will always validate as true for properties of value types. There is no need to get the value to see if it is null - it cannot be.
What do you mean by that a type has side effects? I understand that evaluation of an expression may have side effects. And yes, property getters may have side effects. But, so what? Are you saying that the reason the validation system in the framework
on purpose accesses these value type properties (marked required explicitly or implicitly) is to cause these side effects that might be hiding in property getters?
In addition, one has no control of the order in which the framework validates, and thus accesses, the properties. I am not sure I agree that it is important to get property X (even if we know X will validate as valid because it is of value type) just in
case X's getter has side effects affecting other properties, possibly causing those other properties to become invalid - those other properties might already have been visited and validated by the framework.
levib
If the planned change goes in for MVC 3, then the only property getters called by the server-side validation framework will be those to which any
explicit attributes ([Required] and otherwise) are applied. It seems like this behavior will satisfy everybody.
I still don't see the point of getting a value type property even if it is explicitly marked [Required]. The purpose of the validation system is to validate assertions made about values. [Required] means "has a value" and if the framework can determine
a property has a value without accessing the property then I think it should do so.
You're right that the implementation of [Required] is pretty much just a simple "!= null" check, which is useless for value types. However, you can subclass RequiredAttribute and perform any check or take any action you want from within the IsValid() method,
and we can't just assume that the IsValid() method there is a no-op on value types. So if we find
any explicit attribute - even something that subclasses RequiredAttribute - we have to run it.
Marked as answer by ricka6 on May 18, 2010 11:14 PM
I see - you meant attributes that are subtypes of RequiredAttribute.
Such attributes, though, are not THE RequiredAttribute, they are not [Required]. It is a whole different attribute and obviously the framework would have to let such an attribute do its thing - access the property and get the value to validate it.
But, in the vast, vast majority of cases when the attribute is [Required] or derived from it, it will be [Required] not a subtype. And I think in those majority of cases it would be good if the framework detected that, used its special knowledge of what
[Required] means, and didn't bother accessing the property if it is a value type. Regardless whether [Required] was used implicitly or explicitly.
edwinvandebu...
0 Points
10 Posts
UpdateModel calls a property get on the model
May 04, 2010 02:08 PM|LINK
Hello all,
Has the behaviour of the UpdateModel<T> changed in MVC 2 (RTM)? Since then I have the following problem when UpdateModel is called:
UpdateModel<T1>(record, properties);
record is typeof(Jumbo.Juist.Models.Bezorging) and properties is a string[] containing "Winkelnummer" and "OudRoutenummer".
This now fails, because a get-property is being accessed: BerekendeAankomstTijd. In the past, it didn't fail. IMHO, this validation should be skipped, because it's only a getter (and thus/also not included in the string[] of properties to update).
Is there a way to do an UpdateModel without validation of "untouched" properties?
Of course I fixed this problem by doing a check in the property getter, but I'm just annoyed that my properties are accessed with an UpdateModel call.
By the way, the stack trace is:
Juist.DLL!Jumbo.Juist.Models.Bezorging.BerekendeAankomstTijd.get() Line 147 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.dll!System.ComponentModel.ReflectPropertyDescriptor.GetValue(object component = {Jumbo.Juist.Models.Bezorging}) + 0x65 bytes
System.Web.Mvc.dll!System.Web.Mvc.AssociatedMetadataProvider.GetPropertyValueAccessor.AnonymousMethod() + 0x13 bytes
System.Web.Mvc.dll!System.Web.Mvc.ModelMetadata.Model.get() + 0x17 bytes
System.Web.Mvc.dll!System.Web.Mvc.DataAnnotationsModelValidator.Validate.MoveNext() + 0x30 bytes
System.Web.Mvc.dll!System.Web.Mvc.ModelValidator.CompositeModelValidator.Validate.MoveNext() + 0x13c bytes
System.Web.Mvc.dll!System.Web.Mvc.DefaultModelBinder.OnModelUpdated(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext = {System.Web.Mvc.ModelBindingContext}) + 0x89 bytes
System.Web.Mvc.dll!System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext, object model) + 0x3d bytes
System.Web.Mvc.dll!System.Web.Mvc.DefaultModelBinder.BindComplexModel(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext) + 0x419 bytes
System.Web.Mvc.dll!System.Web.Mvc.DefaultModelBinder.BindModel(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext) + 0x119 bytes
System.Web.Mvc.dll!System.Web.Mvc.Controller.TryUpdateModel<System.__Canon>(System.__Canon model, string prefix, string[] includeProperties, string[] excludeProperties, System.Web.Mvc.IValueProvider valueProvider) + 0x1c2 bytes
System.Web.Mvc.dll!System.Web.Mvc.Controller.UpdateModel<Jumbo.Juist.Models.Bezorging>(Jumbo.Juist.Models.Bezorging model, string prefix, string[] includeProperties, string[] excludeProperties, System.Web.Mvc.IValueProvider valueProvider) + 0x43 bytes
System.Web.Mvc.dll!System.Web.Mvc.Controller.UpdateModel<System.__Canon>(System.__Canon model, string[] includeProperties) + 0x4b bytes
> Jumbo.MVC.DLL!Jumbo.MVC.Controllers.BaseController<Jumbo.Juist.Models.JuistDataContext,Jumbo.Juist.Models.Bezorging>.InternalUpdateModel<Jumbo.Juist.Models.Bezorging>(Jumbo.Juist.Models.Bezorging record = {Jumbo.Juist.Models.Bezorging}, string[] properties = {string[2]}) Line 345 + 0x42 bytes C#
bug UpdateModel mvc2
HeartattacK
All-Star
55262 Points
5917 Posts
Moderator
MVP
Re: UpdateModel calls a property get on the model
May 04, 2010 03:31 PM|LINK
I believe MVC 2 has switched to model based validation. What that means is that say you have this class:
student: id, name, age, gender
and say name, age and gender are required.
If a form previously submitted only name and age but not gender, then it would have passed validation (i.e. gender wasn't posted, so it's not validated.)
In MVC 2, they've changed that so even if gender is not passed, validation will be carried out on name, age AND gender.
Perhaps this is the issue you're running into.
blog: www.heartysoft.com
twitter: @ashic
fastfasterfa...
Participant
919 Points
206 Posts
Re: UpdateModel calls a property get on the model
May 04, 2010 03:33 PM|LINK
http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html might be of interest.
edwinvandebu...
0 Points
10 Posts
Re: UpdateModel calls a property get on the model
May 05, 2010 07:26 PM|LINK
Thanks for the link. Although it doesn't address the problem of readonly properties being checked during model validation, some user comments directed me to:
http://stackoverflow.com/questions/2211829/why-does-asp-net-mvc-care-about-my-read-only-properties-during-databinding
Which provided the answer (and a link to the original answer):
-----
I believe I'm experiencing a similar issue. I've posted the details:
http://forums.asp.net/t/1523362.aspx
edit: Response from MVC team (from above URL):
We investigated this and have concluded that the validation system is behaving as expected. Since model validation involves attempting to run validation over all properties, and since non-nullable value type properties have an implicit [Required] attribute, we're validating this property and calling its getter in the process. We understand that this is a breaking change from V1 of the product, but it's necessary to make the new model validation system operate correctly.
You have a few options to work around this. Any one of these should work:
-----
I don't like this change in MVC2; unfortunately there is not an easy way to get the MVC1 behaviour...
fastfasterfa...
Participant
919 Points
206 Posts
Re: UpdateModel calls a property get on the model
May 05, 2010 09:29 PM|LINK
I consider it a bug that ASP.NET MVC runs [Required]-validators on value types. It is completely unneccessary and a waste of processor time since such a validation cannot fail, ever.
edwinvandebu...
0 Points
10 Posts
Re: UpdateModel calls a property get on the model
May 05, 2010 09:53 PM|LINK
Well, it can fail, like in my case, when an exception is thrown, so the only reason for this check would be exactly that case.
Nevertheless, I think it should never be done on get-only properties, because they should be dependend on other (settable) properties (they could also depend on fields, of course, but in that case property validation isn't enough anyway). Therefore, validating the set-properties and validating the model should suffice.
The DataAnnotations attributes provide for all kind of checks, but unfortunately lacks an attribute for "do not check". So, according to me, the beste would be
* run [Required]-validators on value-types when there is a set-accessor, unless marked as [DoNotValidate]
* don't run [Required]-validators on value-types when there is only a get-accessor, unless marked as [Required] explicitely.
levib
Star
7702 Points
1099 Posts
Microsoft
Re: UpdateModel calls a property get on the model
May 05, 2010 10:51 PM|LINK
This is incorrect. Subclassed types of [Required] can have side effects, so we have to run all attributes that we find.
The particular issue under discussion here is whether the framework should implicitly add [Required] to value-type properties. This was done so that client-side validation works properly. We probably should have been smarter about saying that the implicit [Required] should be added only during client validation, not during server validation (and there's a work item to do precisely this in MVC 3). The switch mentioned earlier in this thread will toggle the implicit attribute for both client + server validation.
If the planned change goes in for MVC 3, then the only property getters called by the server-side validation framework will be those to which any explicit attributes ([Required] and otherwise) are applied. It seems like this behavior will satisfy everybody.
fastfasterfa...
Participant
919 Points
206 Posts
Re: UpdateModel calls a property get on the model
May 06, 2010 12:36 AM|LINK
If a value is of a value type then by definition it will have a value. Thus, [Required] will always validate as true for properties of value types. There is no need to get the value to see if it is null - it cannot be.
What do you mean by that a type has side effects? I understand that evaluation of an expression may have side effects. And yes, property getters may have side effects. But, so what? Are you saying that the reason the validation system in the framework on purpose accesses these value type properties (marked required explicitly or implicitly) is to cause these side effects that might be hiding in property getters?
In addition, one has no control of the order in which the framework validates, and thus accesses, the properties. I am not sure I agree that it is important to get property X (even if we know X will validate as valid because it is of value type) just in case X's getter has side effects affecting other properties, possibly causing those other properties to become invalid - those other properties might already have been visited and validated by the framework.
I still don't see the point of getting a value type property even if it is explicitly marked [Required]. The purpose of the validation system is to validate assertions made about values. [Required] means "has a value" and if the framework can determine a property has a value without accessing the property then I think it should do so.
levib
Star
7702 Points
1099 Posts
Microsoft
Re: UpdateModel calls a property get on the model
May 06, 2010 12:44 AM|LINK
You're right that the implementation of [Required] is pretty much just a simple "!= null" check, which is useless for value types. However, you can subclass RequiredAttribute and perform any check or take any action you want from within the IsValid() method, and we can't just assume that the IsValid() method there is a no-op on value types. So if we find any explicit attribute - even something that subclasses RequiredAttribute - we have to run it.
fastfasterfa...
Participant
919 Points
206 Posts
Re: UpdateModel calls a property get on the model
May 06, 2010 01:19 AM|LINK
I see - you meant attributes that are subtypes of RequiredAttribute.
Such attributes, though, are not THE RequiredAttribute, they are not [Required]. It is a whole different attribute and obviously the framework would have to let such an attribute do its thing - access the property and get the value to validate it.
But, in the vast, vast majority of cases when the attribute is [Required] or derived from it, it will be [Required] not a subtype. And I think in those majority of cases it would be good if the framework detected that, used its special knowledge of what [Required] means, and didn't bother accessing the property if it is a value type. Regardless whether [Required] was used implicitly or explicitly.