The model validation in MVC is brilliant but for best usage requires Attributes to be added to your model.
If you use Entity Framework to generate your model you are given classes which will be overwritten when you regenerate the model as seen in the warning automatically appended to your file:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
The way around this is to use a Metadata Class. Because an Entity Framework model class is defined as a partial class you can extend it.
For the following model class:
namespace Project.EntityFramework
{
using System;
using System.Collections.Generic;
public partial class Dog
{
public Dog()
{
this.Collars = new HashSet<Collar>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Collar> Collars { get; set; }
}
}
You can extend the partial class as long as your class is in the same namespace. The specific metadata file is shown:
using System;
using System.ComponentModel.DataAnnotations;
namespace Project.EntityFramework
{
[MetadataType(typeof(Dog.DogMetadata))]
public partial class Dog
{
internal sealed class DogMetadata
{
#pragma warning disable 0649
private DogMetadata() { }
[Editable(false)]
public object Id { get; set; }
[Display(Name = "Woofy Name")]
[Required(ErrorMessage = "Name Is Required", AllowEmptyStrings = false)]
[MinLength(10)]
public object Name;
[Editable(false)]
public object Collars { get; set; }
}
}
}
This Metadata file Dog.Metadata.cs
is in the same folder and namespace (folder is not always equal to namespace but by default in visual studio) as the model DatabaseModel.edmx
. Metadata files have .metadata
in the name by convention.
The fact metadata is being used is declared with the attribute:
[MetadataType(typeof(Dog.DogMetadata))]
Where the type is the metadata class you're using. Therefore it is possible to define the metadata class separately in another file but it's best to keep everything together.