I have an N tier app in which Data, Domain and the front-end layers are in separate projects. I am using ASP.NET MVC to create the website and I am trying to add validation rules by using System.ComponentModel.DataAnnotations. Currently I have done it on the domain classes' properties. I would like to know whether it is a good practice to apply the validation rules directly to the Domain classes? Or it is better to create ViewModels classes in the ASP.NET app and apply the validation rules to the properties of the ViewModel classes? Hope this question fits here I appreciate any help.
-
3Better to create ViewModels – Brian Ogden Jul 18 '17 at 21:36
-
@BrianOgden Thanks a lot for your help. Then I will use automapper to map Domain classes to view model classes. Any better suggestion if I may ask? – arvind Jul 18 '17 at 21:44
2 Answers
ViewModel is much better, because ViewModel should understand if it gets valid input from the user. And then you can fix all other exception during convertion using AutoMapper. I would also create a lot of custom , DataAnnotations, DataTypes, Editors, ModeMetaDataRules, and ModelBinder to go with app.
Here is parts of code for ModelFilter using custom ModelBuilder, I am going post part of it, because there is a lot of code involved, but it should get you on right track.
public interface IModelMetadataFilter
{
void TransformMetadata(ModelMetadata metadata,
IEnumerable<Attribute> attributes);
}
public class MultilineTextByNameConvention : IModelMetadataFilter
{
public void TransformMetadata(ModelMetadata metadata, IEnumerable<Attribute> attributes)
{
if ( !string.IsNullOrEmpty(metadata.PropertyName) &&
string.IsNullOrEmpty(metadata.DataTypeName) )
{
if ( metadata.PropertyName.ToLower().Contains("notes")
|| metadata.PropertyName.ToLower().Contains("description")
|| metadata.PropertyName.ToLower().Contains("comment")
)
{
metadata.DataTypeName = DataType.MultilineText.ToString();
}
}
}
}
This code looks for every ViewModel that has property name containing words 'notes', 'description', and 'comment', automatically applying Multitext DataType attribute for all that properties. This type of code can be used for a lot of other different situations. For example fields like SSN can have particular format using RexExpr DataAnnotation, and so on...

- 111
- 5
-
-
Thanks for adding the code snippet. Your answer was exactly what I wanted :) – arvind Jul 20 '17 at 07:39
You can set attributes on partial classes of your entities and your auto generated classes will not get overridden.
For instance,
Let's say you have entity TheEntity
In a separate file with the Same namespace you can write:
namespace SameNamespaceAsEntities
{
internal sealed class TheEntityMetadata
{
//AStringInTheEntity appears twice in your project
//once in the auto gen file, and once here
[Required(ErrorMessage = "Field is required.")]
public string AStringInTheEntity{ get; set; }
}
//http://stackoverflow.com/questions/14059455/adding-validation-attributes-with-an-entity-framework-data-model
[System.ComponentModel.DataAnnotations.MetadataType(typeof(TheEntityMetadata))]
public partial class TheEntity : IEntity //you can set contracts
{

- 2,094
- 1
- 8
- 20
-
-
What is wrong with the solution @Ssheverdin has offered?Plus,I am not sure if I understand your suggestion to be honest.Explain more?I have my Domain classes in an different project.Pis I need to apply data annotations without touching model classes.Lets say I have a property called Name and I want to apply [StringLength].What if another project wants to use my domain project DLL and does'nt need the StringLength limitation.Therefore,the solution Ssheverdin has offered here sounds quite reasonable.But I still am open to suggestions. Till then I respectfully will choose Ssheverdin solution. – arvind Jul 19 '17 at 09:04