6

I have a user model with two [NotMapped] string properties Password and ConfirmPassword. These are unmapped because I save password as byte array (after salting) so there are two additional properties (mapped) InternalPassword and Salt in user model.

The problem is when I use the user model to change password, entity framework throws DBEntityValidation error stating "The Password property is required." What I understand here is that EF is trying to validate my model before saving and since Password/ConfirmPassword are not set, it is throwing this error. This raises following questions:

1) If property Password is explicitly annitated as [NotMapped], why is EF validating it during save? 2) IF EF performs validation during save, and the same is also performed during binding (I.E. in the controller action method), does it not hurt performance? (validating twice) 3) What's the recommended way to resolve this error? (If I explicitly set Password property to dummy value, error is gone.)

Edit: I've removed the code since it is lengthy and may be the cause of no answer yet. If somebody wants to have a look, I can append it below.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
Varun K
  • 3,593
  • 2
  • 25
  • 26
  • This is strange because even if the `Password` property is mapped it would not be required by default since `string` properties are never required unless you specify this explicitely - putting `[Required]` attribute on the property or calling `IsRequired()` in Fluent API. Do you have such settings for the `Password` property? – Slauma Aug 13 '11 at 19:48
  • @Slauma yes I have required attribute specified on Password. This is needed to prompt user to fill in password field during registration. But since this is not mapped, why EF attempts to validate it during save? – Varun K Aug 14 '11 at 05:13

2 Answers2

10

Automatic validation in EF is somehow strange feature - I don't like it. You can read this article to find some information how to validate just selected properties but I expect you must trigger that validation manually and turn off global validation by calling:

context.Configuration.ValidateOnSaveEnabled = false;

Your problem with NonMappedAttribute is interesting. I didn't go deep into implementation of validation in EFv4.1 but if the implementation is build around the same rules as common validation based on data annotations, it uses only attributes derived from ValidationAttribute - NotMappedAttribute is not derived from ValidationAttribute.

That is another problem of such implementation - it combines mapping definition and validation but these two features are not the same and should not be implemented by the same API.

@alun deleted his answer - the valid answer to your question. Your validation belongs to view model dependent on the operation a user is performing. It doesn't belong to persistence model. Why? Exactly because of your current issue - persistence model can hold only single validation set and every operation in your application must ensure that validation criteria for that set are met = you must ensure that Password and ConfirmPassword are filled even if your current operation doesn't demand it => problem.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • I have different models for registration and change password. The problem is that the registration model (User) represents the db table directly with those two additional UI only string properties for password. I could have created a separate (view) model for registration but that would cause duplication and unnecessarily copying registration model values into User model. – Varun K Aug 14 '11 at 15:14
  • I too found out and had implemented ValidateOnSaveEnable before this answer and it seems to be the only visible solution at present. – Varun K Aug 14 '11 at 15:21
  • That is not duplication. That is separation of concerns. – Ladislav Mrnka Aug 14 '11 at 16:03
0

Old thread but since I faced the exact same issue with EF6, please allow me to share my experience, in case someone else is searching the same thing.

Issue: Exact the same: Password & ConfirmPassword 2 [NotMapped] fields of User class. When trying to save New record, I was getting validation exception that both fields were required.

Investigation: I noticed that when I was updating the user record, I had no problem. Searching for what is the difference, I saw that I had overridden the Validate method

public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

for validating the MVC model, and the EF6 was displaying my custom error message! Voila! EF6 used also this Validate method! (and due to a bug in my code, it was triggering the error).

Conclusion: When saving an entity, EF6 will trigger the Validate method and any 'ValidationResult' will prevent record for saving.

Panos
  • 579
  • 4
  • 2