What you're doing is not validation, but verification. Avoid heavy logic with dependencies in attribute code.
Validation is concerned with "static" matters: data formats, lengths, very basic logic, the kind of things you'd use a regular expression for. That is: the data is valid, but not necessarily verified.
Verification is where you verify the provided data, this requires you to connect to a database or other external data to check it out, due to the extra legwork required it is an expensive process and should appear as part of your main business logic (as these are business rules that you're executing).
So your ViewModel should look like:
[Required]
public String CourseName { set; get; }
And your Controller should look like:
[HttpPost]
public ActionResult Create(CoursesViewModel viewModel)
{
if( !this.IsCoursesViewModelValid( this.db, viewModel ) ) {
this.ModelState.AddError("some error message");
return this.View();
}
DBCourse dbCourse = new DBCourse();
dbCourse.Name = viewModel.CourseName;
db.Courses.Add( dbCourse );
db.SaveChanges();
return this.View();
}
private Boolean IsCoursesViewModelValid(DataContext db, CoursesViewModel viewModel) {
return db.Courses.Where( dbC => dbC.CourseName == viewModel.CourseName ).Count() == 0;
}
Important note: Do not use DB Entity classes as ViewModels! Your ViewModels should be separate POCO classes that contain only state and data for the view. There are numerous reasons not to use DB Entities as ViewModels:
- Security. A malicious user could set any entity data member by taking advantage of default model-binding behaviour
- It keeps the separation-of-concerns. Your view should know nothing of your database. If you refactor your DB schema you'll need to update your views because the references will be broken
- Data members and View-model fields don't match: consider a view for a
Users table. Your form would want two password fields ("Enter a new password" and "Confirm your password") which should be text, but your database won't have a password column, it will have a binary PasswordHash and PasswordSalt column, which doesn't match your form at all.
valueinto acourses, don't justToStringit.