Code first: does fluent api influence UI? - asp.net-mvc

I'm reading a book written by Julie Lerman on Code First. According to the book, annotations and fluent api give the same result. Everything depends on the style of the developer.
I know that annotations allow both to configure how code first generate database objects and how MVC customize UI elements. Let's say I use [Required, MaxLength(50)]. The attribute will generate a NOT NULL, nvarchar (50) in the database. It also will validate the input for that field.
[Required, MaxLength(50)]
public string Name { get; set; }
What if I decide to use Fluent API to configure Code first. Am I still going to need annotations to influence UI elements or using fluent API is going to be enough?
EDIT
How about annotations, such as Display that serve only for UI purposes? Do they have equivalents? If not, Will I need to use annotaions?
[Display(Name = "Date of Birth")]
public DateTime BirthDate { get; set; }
Thanks for helping

Data Annotation is the simplest way of telling a class to enforce some validation rule. You can do the same thing with Fluent API as well. Some people like doing it by data annotations and some people like it by doing with fluent API
Reasons to like it with Data Annotations
1) Keep the validation info about my entity in one place along with the entity definition
Reasons to like it with Fluent API
1) Keep my entity clean. It will have only my property info. No validation info. Clean and simple POCO. I will write validation on the OnModelCreating method in my data context class.
You can not do all Fluent API things with Data Annotations way. the same way you don't have few Data Annotations attributes equivalant not present with Fluent API way ( Ex : HasMinLength) . HasMinLength is something we will for our Model validation which usually makes sense in the UI.
For the UI Model Validation, you can not use the Fluent API alone. Fluent API's major role is to look into the fluent configuration we writes and act when creating the Model(Database) from the entities. Remember we are overriding the OnModelCreating method to write our fluent API configuration. So for the UI Validation (of my ViewModel), I would use the DataAnnotation way and use fluent API if i want to define some thing related to my datamodel like Define a foreign key or Map this Entity to a Table with different name etc..
EDIT : As per the question edit,
You should make use of the Data Annotations in this case. If you are doing code first. You may remember that that entity is going to be your Database table ( of course you can tell EF to ignore /rename specific columns). In that case, I would keep my Entities clean and Create a ViewModel which i will use in my UI. I will add my DataAnnotations in my ViewModel to handle it. I may write some mapping code which maps data from ViewModel to Model and Model to ViewModel wherever necessary.

If your entity model classes are doubling as your viewmodel classes, AND you are using the default out of the box DataAnnotationsValidationProvider, then you would need the dataannotations attributes on the model properties to get validation.
However, you should not double your entity classes as viewmodel classes. Take for instance, a controller that needs to have a ReturnUrl property in its model. You wouldn't want this in your entity model / database. Because of differences like this between the View model and the Entity model, the 2 should really be separate (yet cohesive) layers in your application. You can make them cohesive using a library like AutoMapper.
This is one of the reasons I prefer the fluent API. If you stick to the fluent API, then you would never put any attributes on any entity model classes or properties. When it comes time to show, insert, or update data, you put the attributes on the viewmodel classes only.
Also, the [Required] attribute on an entity type performs validation during SaveChanges, whereas a [Required] attribute on a viewmodel performs validation during model binding.

According to Julie Lerman's book on DbContext, you do NOT need any additional annotations to your Fluent API configuration. The Name property will get validated by Validation API as if it had been configured with Data Annotations.
According to the same book, MaxLength and Required are the only validation attributes with fluent API conterparts.

Related

MVC Model binding / validation

After a year or so of MVC experience I'm still confused about one thing: How to effectively use the DataAnnotations with ModelState.IsValid? For simple tutorial example this all works just fine and I have no questions about that. But supposed I have the following model:
Public Class Movie
Public Property MovieID As Integer
Public Property Title As String
Public Property Year As Integer
Public Property AddedByUser As String
End Class
Now the field AddedByUser is required in the database however I don't want the user to provide this but rather the business logic based on the currently logged in user. How would I use the DataAnnotation attributes for this scenario? If I make this field required then in the controller when I say:
Public Function SaveMovie(ByVal entity as Movie) As ActionResult
If ModelState.IsValid
// Save to DB here...
End If
Return View(entity)
End Function
... the validation will fail because I don't have that field in the view bindings. Should I have a hidden field for this? Should I write a custom view model for SaveMovie action? I suppose I could write my own validation in business logic but then why use model validation at all? Custom model binder perhaps? What is the best way to handle these types of scenarios?
Just to give another example scenario what about the difference between insert and update operation and validation? For update operations object's primary key is required. However that is not the case for inserts. Are you supposed to have separate models for insert and update just because of this one key property?
so the way that I handle this is I use the DataAnnotation based validation for user input type stuff. i.e. Validation on email addresses, dates, required fields etc. Stuff that you need a quick 'sanity check' on and need to double check the users entries on.
I don't put any DataAnnotations on the fields that my Database controls or my code controls, i.e. Primary Keys, your [AddedByUser] property as the user doesn't access these properties directly and so you shouldn't have to add validation checks on this. Since your code is the only thing that updates these properties, why validate them?
For more 'business rule' type validation I implement IValidatableObject on my model which gets run, in MVC, after all property-level validations have succeeded. Note that it won't run if the property-level validations fail. And this makes sense, because if the data is 'dirty' you wouldn't want to proceed to run more complex validation etc.
Hope this helps :)

Entity Framework 4.1 - Code First with existing Database, how to define classes, using Attributes or EntityTypeConfiguration? What is the difference?

I have been studying the EF for a short time and cant find the answer to this question.
I have existing database and I am using CodeFirst to create classes for the model.
What is the difference in using Attributes and EntityTypeConfiguration to define parameters of table columns?
Since the database already has defined foreign keys and unique constraints, and so on, how and where to implement the validation for a best and most fluid result for use in ASP.NET MVC3?
Is it better to implement Attributes and CustomValidation or to use TryCatch blocks to catch errors from db?
Does Validator.TryValidateObject(myModelObject, context, results, true); use validation rules defined only as Attributes or can it use rules defined in EntityTypeConfiguration?
Thank You
Get the Entity Framework Power Tools CTP1 and it will reverse engineer your database and create entities, and a full data mapping. This is different than Model or Database first in that it generates a fluent model rather than using an .edmx file. You can see exactly how it works then.
See the following article about how you can create your entity classes from existing database :
http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-model-amp-database-first-walkthrough.aspx
Code generation templates will do the work for you, you don't need to write them if you have an existing db.
For validation, you can create new partial classes under the same namespace and put DataAnottations for your properties. Here is an example for you :
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
namespace TugberkUgurlu.App1.DataAccess.SqlServer {
[MetadataType(typeof(Country.MetaData))]
public partial class Country {
private class MetaData {
[Required]
[StringLength(50)]
[DisplayName("Name of Country")]
public string CountryName { get; set; }
[Required]
[StringLength(5)]
[DisplayName("ISO 3166 Code of Country")]
public string CountryISO3166Code { get; set; }
[DisplayName("Is Country Approved?")]
public string IsApproved { get; set; }
}
}
}
-Since the database already has defined foreign keys and unique constraints, and so on, how and where to implement the validation for a best and most fluid result for use in ASP.NET MVC3?
These should happen via your generated model. Keys are automatically inferred. If you reverse engineer an existing database the attributes will be created for you. If not, there are basic rules that are followed. The entity framework will attempt to use an auto incrementing primary key for example unless you tell it otherwise via
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
The relationships are already part of your model so there is your referential integrity, and the data annotations will define the validation rules.
-Is it better to implement Attributes and CustomValidation or to use TryCatch blocks to catch errors from db?
Implement attributes. Define your metadata classes with your attributes in them.
In addition you want to catch any db errors for anything else that is unexpected if your db has additional logic in there not defined in your model (try catch at some level should generally be used anyways for logging purposes_
-Does Validator.TryValidateObject(myModelObject, context, results, true); use validation rules defined only as Attributes or can it use rules defined in EntityTypeConfiguration?
As far as I'm aware only the attributes are used. I'm going to try to test this later though as I'd like a definite answer on this as well :)

MVC3 Validation with Entity Framework Model/Database First

I want to use MVC 3 and the Entity Framework for my application.
The model will be stored in a different assembly to the MVC app.
The choice I'm making is either to use the EF to generate my entities or to use code first.
With code first, I can decorate members with [Required] etc... But how would I go about adding those attributes if EF has generated entities from the DB?
Having EF generate my entities will save a lot of time, but I want MVC to auto populate the validation depending on how I've decorated my members. Does this make sense? If so, how would I do that?
In that case, MetadataTypeAttribute is used. You can combine it with partial classes to achieve desired results
And by the way, in your place i would do more research when deciding between using Database First and Code First designs. That all is not about saving time when generating entities, there's much more difference between those two approaches. For the time saving purpose, you can use EF Power Tools to generate code first entities from database - simple.
Better than auto generating your entities, I recommend you to use Code First or mapping an existing database to POCO's classes (not generating the entities, just creating them by hand and mapping them to the existing database)
Scottgu wrote about using EF "Code First" with an existing database.
Check this out:
In your model template (file with extension model.tt) you can hack this template for generating decorators, in this example I add the [Required] decorator plus an error message
var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
if(!edmProperty.Nullable)
{#>
[Required(ErrorMessage="<#=String.Format("The field {0} is required",edmProperty.ToString())#>")]<#
}#>
<#=codeStringGenerator.Property(edmProperty)#><#
}
}
So the result is something like this
[Required(ErrorMessage="The field Id is required")]
public long Id { get; set; }
PS: You can also add the
using System.ComponentModel.DataAnnotations; by editing the template.
Hope this can help you up.

DRY Validation with MVC2

I'm trying to figure out how I can define validation rules for my domain objects in one single location within my application but have run in to a snag...
Some background: My application has several parts:
- Database
- DAL
- Business Logic Layer
- SOAP API Layer
- MVC website
The MVC website accesses the database via the SOAP API, just as third parties would. We are using server and and client side validation on the MVC website as well as in the SOAP API Layer.
To avoid having to manually write client side validation we are implementing strongly typed views in conjunction with the Html.TextBoxFor and Html.ValidationMessageFor HTML helpers, as shown in Step 3 here. We also create custom models for each form where one form takes input for multiple domain objects.
This is where the problem begins, the HTML helpers read from the model for the data annotation validation attributes. In most cases our forms deal with multiple domain objects and you can't specify more than one type in the <%#Page ... Inherits="System.Web.Mvc.ViewPage<MvcApplication.Models.SomeModel>" %> page directive. So we are forced to create a custom model class, which would mean duplicating validation attributes from the domain objects on to the model class.
I've spent quite some time looking for workarounds to this, such has referencing the same MetadataType from both the domain class and the custom MVC models, but that won't work for several reasons:
You can only specify one MetadataType attribute per class, so its a problem if a model references multiple domain objects, each with their own metadata type.
The data annotation validation code throws an exception if the model class doesn't contain a property that is specified in the referenced MetadataType which is a problem with the model only deals with a subset of the properties for a given domain object.
I've looked at other solutions as well but to no avail. If anyone has any ideas on how to achieve a single source for validation logic that would work across MVC client and server side validation functionality and other locations (such as my SOAP API) I would love to hear it!
Thanks in advance,
Matthew
What you should do is instead of trying to replicate the structure in the view models, use your existing models in the data model classes.
When you bind the form data back to the view model, you can restrict which columns will be bound back using the [Bind] attribute on the parameter. Or use any other approaches to do this.
So if your model creates classes like Product User and Category, and your view model needs to use some of their properties, create a view model like this:
public class PageViewModel
{
public Product Product { get; set; }
public Category Category { get; set; }
public User User { get; set; }
}
In your page you will be able to use them with
<%: Html.EditorFor(m => m.Product.ProductName) %>
In this case the validation attributes from your actual classes will be used, as required.
Does that give you an acceptable solution?
How about returning a container class that has nested types in your action method?
http://weblogs.asp.net/blogs/rajbk/image_63B7D5D4.png

Does ASP.Net MVC 2 validation need some more thought in terms of patterns and use?

Here is the lay of the land. Like most people I have my domain object and I have my view models. I love the idea of using view models, as it allows for models to be created specifically for a given view context, without needing to alter my business objects.
The problem I have is with type level validation defined on my domain object and getting those rules to the client. In this case lets say I am using data annotations to describe the validation rules, when I move the data from the domain object to the view model, the view model no longer knows what validation it should get the interface to perform (because the validation is defined back on the domain object).
With MVC 2 you can get it to automatically perform client/server side validation, based on the validation rules of the current object. But because the validation rules are defined on the domain object and not the view model, I would have to duplicate the validation rules on the view model to get this to work.
How do others deal with this type of issue? My thinking is that besides mapping the data from the domain object to the view model, we also need to map across the validation rules, but I haven't really seen others talking about this issue... Brad Wilson has recently talked about this issue at length but hasn't really addressed the duplication of rules on the domain object and on the view models... what are your thoughts?
Cheers
Anthony
The DataAnnotation attributes are about validating input and giving UI feedback to the end user. That's really their only intended use. I use different validation strategies for UI objects and business objects, so the DA validation attributes only end up on models being shown to the user.
This may not be appropriate, but what if you just moved your validation rules/annotations from your Models to your ViewModels? In a few of the projects I've been on, we've chosen to prevent the View from accessing anything but information exposed through its corresponding ViewModel. Since all data interaction would be performed through the ViewModel, there wouldn't be a need to have validation on your Model objects.
The counter to this argument is that you could easily duplicate certain validation rules, since different ViewModels might be interfacing with the same Models. In this case, it might make sense to simply declare your Model as a property exposed on your ViewModel. For postbacks, they could accept a Model as their parameter, allowing the ModelBinder infrastructure to handle the request. In this case, if ModelState.IsValid is false, you could just reassign the property to your ViewModel before redisplaying the View.
I would recommend moving your annotations to your ViewModels. It makes sense since a lot of Views are a) the result of composition of several models or b) a subset of model data.
It turns out that AutoMapper may be able to do this for us automagically, which is the best case scenario.
AutoMapper-users: Transfer validation attributes to the viewmodel?
http://groups.google.com/group/automapper-users/browse_thread/thread/efa1d551e498311c/db4e7f6c93a77302?lnk=gst&q=validation#db4e7f6c93a77302
I haven't got around to trying out the proposed solutions there, but intend to shortly.
(Cross posted this on my (dupe) question as well).
Probably we shouldn't use view models at all?
And define validation rules on model layer entities..
I've been considering this as well for a while now. I totally understand Brad's reply. However, let's assume I want to use another validation framework that is suitable for annotating both domain entities and view models.
The only solution I can come up with on paper that still works with attributes would be to create another attribute that "points" to a domain entity's property that you are mirroring in your view model. Here's an example:
// In UI as a view model.
public class UserRegistration {
[ValidationDependency<Person>(x => x.FirstName)]
public string FirstName { get; set; }
[ValidationDependency<Person>(x => x.LastName)]
public string LastName { get; set; }
[ValidationDependency<Membership>(x => x.Username)]
public string Username { get; set; }
[ValidationDependency<Membership>(x => x.Password)]
public string Password { get; set; }
}
A framework like xVal could possibly be extended to handle this new attribute and run the validation attributes on the dependency class' property, but with your view model's property value. I just haven't had time to flesh this out more.
Any thoughts?

Resources