I'm building an application using MVC 3 and Entity Framework 4.
I've created my Entity Data Model and generated a database from it.
Now I know the validation attributes such as [Required] or [StringLength(5)] can be used on the model properties to provide validation both clientside and serverside.
I would like to know if these attributes can also be generated dynamically instead of having to add them to the model explicitly? I saw that in EF 4.1 RC you can make use of the Fluent API to further configure your model in the OnModelCreating method by using the DbModelBuilder class.
As shown here
I'm working with a framework however that still uses ObjectContext instead of DbContext so I would like to know if the above solution can be used in combination with ObjectContext?
As a final note, since I've been trying to figure out how to generate and use data annotations it seems using view models would increase the complexity of validation. From what I read here it seems that just passing the models directly to the view would remove the need to add annotations to the models as well as the view models. However that means that you can no longer use strongly typed views when you do joins on the models and pass those to the view directly?
No it can't. Fluent API is different approach to describe mapping. You can use fluent API or EDMX (Entity Data Model). Not both. Fluent API also works only with DbContext API. If you want to have annotations generated you can try to modify T4 template generating your classes.
I have come across a disturbing issue when using poco classes that are extending base classes.
For example, let say you have a Person poco class that has a strongly typed Car property. You also have a Spouse poco that also uses the Car Property.
Now you want to display "Person Car" and "Spouses Car" in the view using the Display("Name = xxx") attribute. You cant!!! Becareful of this issue if you are not using flat View Models
Related
If you're not coding up POCO's and you're forced to use the model generated by Entity Framework or one of the extensions, is there any way to annotate the model other than:
1) Using a view model
and
2) Annotating the model generated by EF, which should of course be ruled out as it will anyway be over-written every time the model is updated or refreshed from the database?
I do not know if I understand your question, but seems you need write DataAnnotatios to Model autogenerated by EF and the DataAnnotations can't be lost when you update the EF. If it is you need see: this post.
Using EF 4.1 in MVC 3 environment. I'm also using the POCO generation tool I downloaded using NUGET.
I am looking for a way to "customize" the POCO classes with attributes for validation without losing these changes every time the database changes (and a resulting re-sync is performed).
I've tried creating abstract classes and instantiating an inherited class, but EF forces me to create a concrete class through the EDMX file and this descendant class also becomes a generated POCO which is "refreshed" with every database sync.
I've notice the POCO's were partial classes meaning I could add members to the classes in a different file, but this approach wouldn't let me add to existing members.
While I understand that what I'm running into is a limitation of the database first approach, I suspect that there is a way to alter/customize the POCOs in a way that isnt lost with each re-fresh.
You have at least 2 options:
Implement the IValidatableObject interface on your partial class and provide the Validate method.
As Eranga mentions, use the MetadataType attribute to move the validation attributes to another class with the same properties.
Overriding OnModelCreating will only work for code first and isn't an option in model / database first.
I am using Entity Framework and generating my POCO classes via T4 - these classes inherit from nothing and are very plain and simple (created via template in vs 2010)
I tried using the Metadatatype Attribute so I could create a buddy class but when I did this I no longer was able to see my properties... if I removed the attribute! the properties appeared.
Anyway, searching deeper I found this statement from Microsoft
The associated class must be used with EDM or LINQ-to-SQL models because CLR types cannot mark existing properties with new attributes. If you are working with CLR objects directly, sometimes referred to as Plain Old CLR Object (POCO) types, you can apply the attributes directly to the model
So it appears it doesn't work. Anyway it's difficult for me to insert my Data Annotation on the MODEL itself because it's created via T4 hence if I edit it and then re-run the tool it will remove all my changes.
There is a pretty strong consensus around SO and the MVC blogosphere that you shouldn't annotate your business/crud/domain classes with attributes. Not only is your entire MVC stack becoming dependent upon your business/database classes but you'll quickly end up with multiple context scenarios ( same Model, different validation rules ) that are impossible to validate with just a single model.
Use separate view models for your screens, annotate those.
Based on your comment: "Data Annotation on the MODEL itself because its created via T4 hence"
What I'm trying to say is put your dataannotations on your viewmodels, leave your POCO models alone.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
ASP.NET MVC - Linq to Entities model as the ViewModel - is this good practice?
Is is OK to use EF entities classes as view models in ASP.NET MVC?
What if viewmodel is 90% the same of EF entity class?
Let's say I have a Survey class in Entity Framework model. It 90% matches data required for view to edit it.
The only difference from what view model should have - is one or several properties to be used in it (that are required to populate Survey object because EF class cannot be directly mapped onto how it's properties are represented (sub-checkboxes, radio groups, etc.))
Do you pass them using ViewData[]? Or create a copy of Survey class (SurveyViewModel) with new additional properties (it should be able to copy data from Survey and back to it)?
Edit:
I'm also trying to avoid using Survey as SurveyViewModel property. It will look strange when some Survey properties are updated using UpdateModel or with default binder, while others (that cannot be directly mapped to entity) - using SurveViewModel custom properties in controller.
I like using Jimmy Bogard's approach of always having a 1:1 relationship between a view and a view model. In other words, I would not use my domain models (in this case your EF entities) as view models. If you feel like you are doing a lot of work mapping between the two, you could use something like AutoMapper to do the work for you.
Some people don't like passing these model classes all the way through to the view, especially as they are classes that are tied to the particular ORM you're currently using. This does mean that you're tightly binding your data framework to your view types.
However, I have done this in several simple MVC apps, using the EF entity type as the Model for some strongly-typed views - it works fine and is very simple. Sometimes simple wins, otherwise you may find yourself putting a lot of effort and code into copying values between near-identical Model types in an app where realistically you'll never move away from EF.
You should always have view models even if they are 1:1. There are practical reasons rather than database layer coupling which I'll focus on.
The problem with domain, entity framework, nhibernate or linq 2 sql models as your view classes is you cannot handle contextual validation well. For example given a user class:
When a person signs up on your site they get a User screen, you then:
Validate Name
Validate Email
Validate Password Exists
When an admin edits a user's name they get a User screen, you then:
Validate Name
Validate Email
Now expose contextual validation via FluentValidation, DataAnnotations Attributes, or even custom IsValid() methods on business classes and validate just Name and Email changes. You can't. You need to represent different contexts as different view models because validation on those models changes depending on the screen representation.
Previously in MVC 1 you could get around this by simple not posting fields you didn't want validated. In MVC 2 this has changed and now every part of a model gets validated, posted or not.
Robert Harvey pointed out another good point. How does your user Entity Framework display a screen and validate double password matching?
On bigger projects, I usually split up business objects from data objects as a matter of style. It's a much easier way to let the program and database both change and only affect the control (or VM) layer.
I have a load of ADO.NET Entities in my MVC project. I was going to use these entities directly from my views/controllers... however, I think it's probably best to use ViewModels which more accurately reflect what the View requires.
I'm looking for a way that I can auto-generate a ViewModel from an existing Entity, i.e., auto-generate the wrapper or adapter pattern from an existing member... Or a T4 template that would loop through the public properties of an Entity, and output properties for the ViewModel... then I can delete the properties I don't need or create aggregate view models etc.
I cannot seem to find anywhere a way to auto-gen a wrapper or adapter pattern class from an existing type?
The idea is then at runtime, use AutoMapper to map between the ViewModel and the Entity.
thanks
You could use AutoMapper to convert from your domain model to a view model. There's a great post from Jimmy Bogard explaining how you could integrate this within your controller actions.
http://weblogs.asp.net/rajbk/archive/2010/05/04/a-basic-t4-template-for-generating-model-metadata-in-asp-net-mvc2.aspx
That can help. It is actually for metadata generation for existing entity types. But you can use it to generate clean view models with data annotations as well. Maybe with a little modification.