Code First Fluent API validation not working
asp.net-mvc-3, c#, ef-code-first, entity-framework, entity-framework-4.3
Solution
You were both right, I was under false assumption.
[Required] is not an equivalent of .IsRequired()
There are several possible solutions:
1) The quick & easy: Attributes
Model Configuration overrides and Validation
With CodeFirst it is possible to override the configuration of the model defined with validation attributes, e.g. in the OnModelCreating method. Reconfiguring model affects validation since validation should use the actual model configuration – blindly use of attributes would cause validation errors for values that could be valid according to the overrides made in OnModelCreating(). Here are the three special cases for overrides made in OnModelCreating:
If a property was decorated with [Required] attribute and was reconfigured as optional (.IsOptional() method) the [Required] attribute will be removed and as a result ignored when validation happens
If a property was decorated with [StringLength] or [MaxLength] attribute and then was configured with new length (.HasMaxLength() method) new maximum length will be used if possible
If a property was decorated with [StringLength] or [MaxLength] attribute and then was defined to be allowed maximum length (.IsMaxLength) then the attribute will be removed (if possible) and the length of the property value will not be checked
Note that the above changes will be effective only if a property was decorated with some validation attributes. So, setting property as required (.IsRequired()) will not cause the property be validated against null value. See EF Feature CTP5: Validation
2) A quick fix but it's a dirty one as Mystere Man suggested http://thedatafarm.com/blog/data-access/capturing-code-first-fluent-api-validationresults-to-display-in-mvc3-views/
http://bradwilson.typepad.com/blog/2010/10/service-location-pt6-model-validation.html
3) The heavy one: The Validation Application Block in Enterprise Library http://bradwilson.typepad.com/blog/2009/10/enterprise-library-validation-example-for-aspnet-mvc-2.html but Enterprise Library is very often considered as an overkill
4) Validation nirvana: FluentValidation looks very promising and I'll definitely give it a try. http://www.nuget.org/packages/FluentValidation.MVC3 Cons: Not the best approach in an n-layer app. It's primarily focused on Views.
5) N-Layer http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs This approach leads to problems with a validation on the client side so it must be solved separately.
Problem
There is a class - it's a common class nothing special: ``` public class Trader{ public Guid UserId {get;set;} public int TraderId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string PhoneNumber { get; set; } public string Skype { get; set; } public string Photo { get; set; } public string Email { get; set; } public virtual User User { get; set; } } ``` Mapping: ``` public TraderMap() { this.ToTable("Trader", "General"); this.HasKey(a => a.TraderId); this.HasRequired(a => a.User).WithMany().HasForeignKey(a => a.UserId); Property(a => a.UserId).HasColumnName("UserID").IsRequired(); Property(a => a.TraderId).HasColumnName("TraderID").IsRequired(); Property(a => a.FirstName).HasMaxLength(50).IsRequired(); Property(a => a.LastName).HasMaxLength(50).IsRequired(); Property(a => a.PhoneNumber).HasMaxLength(25).IsRequired(); Property(a => a.Skype).HasMaxLength(50).IsOptional(); Property(a => a.Photo).HasMaxLength(100).IsOptional(); Property(a => a.Email).HasMaxLength(100).IsRequired(); } ``` When I leave FirstName or other fields that have IsRequired() empty in the form (View) the validation do not kick in. It just runs into the error: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. Unfortunately this error doesn't say too much. I was digging a little deeper but the only thing I was able to get was Invalid column name discriminator. I thought it would be some forgotten inheritance somewhere (for User class) but I haven't found anything suspicious. The problem is that when I use attributes in the Trader class everything works as supposed. ``` public class Trader{ public Guid UserId {get;set;} public int TraderId { get; set; } [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } [Required] public string PhoneNumber { get; set; } public string Skype { get; set; } public string Photo { get; set; } [Required] public string Email { get; set; } public virtual User User { get; set; } } ``` With attributes the validation works ok and @Html.ValidationMessageFor starts to display error messages and it doesn't allow to send NULL values. Do you have any suggestion what would be the problem with my mapping? UPDATE 1 In fact the attributes above are a possible solution to this problem.