Personally, I don't pass any of the 'Entity' objects back to the view. I would create a 'View Model', which would contain just the data needed to present my View and annotations that the client side validation understands and creates approriate rules for.
You *can* add Annotations to your POCO objects that EF is using, however - this breaks a few programming rules. Data Annotations in this context are just about the 'View' so shouldn't be on our entity objects (which are generally a representation of data)
A good example of this is in the 'Account' models that are automatically created by Visual Studio when you create an 'Internet' type project, e.g.
public class ChangePasswordModel
{
[Required]
[DataType(DataType.Password)]
[DisplayName("Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[DisplayName("New password")]
[RegularExpression(@"^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$", ErrorMessage = "Password must contain at least one capital letter and one number")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[DisplayName("Confirm new password")]
[Compare("NewPassword", ErrorMessage="Passwords must match")]
public string ConfirmPassword { get; set; }
}
@model ChangePasswordModel
@{
ViewBag.Title = "Change Password";
}
<h2>Change Password</h2>
<p>
Use the form below to change your password.
</p>
<p>
New passwords are required to be a minimum of @Membership.MinRequiredPasswordLength characters in length.
</p>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true, "Password change was unsuccessful. Please correct the errors and try again.")
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
@Html.LabelFor(m => m.OldPassword)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.OldPassword)
@Html.ValidationMessageFor(m => m.OldPassword)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.NewPassword)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.NewPassword)
@Html.ValidationMessageFor(m => m.NewPassword)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.ConfirmPassword)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.ConfirmPassword)
@Html.ValidationMessageFor(m => m.ConfirmPassword)
</div>
<p>
<input type="submit" value="Change Password" />
</p>
</fieldset>
</div>
}
In this case, our View is bound to our model, which knows nothing about any data or persistence. All the Model knows is what fields it is expecting, data types and validation rules.
The controller method looks something like..
[HttpPost, Authorize]
public ActionResult ChangePassword(ChangePasswordModel model)
{
if (ModelState.IsValid)
{
bool changePasswordSucceeded = this.MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
if (changePasswordSucceeded)
{
return RedirectToAction("ChangePasswordSuccess");
}
else
{
ModelState.AddModelError("", "Some Error Messge to Display.");
}
}
return View(model);
}
The key points are that our view will validate against our simple view model using javascript (if enabled) , the controller will also validate the model and then data collected from the view is passed on to some other Service, in this case the 'MembershipService'
I like this approach, since there is a clear seperation of concerns and every component is doing the job it's supposed to do.