0

Now I have a create form in C# MVC it's called "course" and I have custom validation called courseValidation

I get the error:

Validation failed for one or more entities.
See 'EntityValidationErrors' property for more details.

Models "courses"

[Required]
[courseValidation()]
public string courseName { set; get; }

Controller "courseController"

[HttpPost]
public ActionResult Create(Models.courses course)
{
    course.userId = 13;
    db.courses.Add(course);
    db.SaveChanges();
    return View();
}

and my custom validation courseValidation

public override bool IsValid(object value)
{
    int query = (from res in db.courses
                 where res.courseName == value.ToString()
                 select res).Count();
    if (query == 0)
    {
        return true;
    }
    else
    {
        return false ;
    }
}

I always have the error in savechanges(), but when I removed my custom validation from the model there is no error happening.

3
  • convert value into a courses, don't just ToString it. Commented Oct 16, 2015 at 17:27
  • If you error is in "savechanges()" then it has already passed your validation. So the the first question is, what error are you getting? Commented Oct 16, 2015 at 17:34
  • Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. Commented Oct 16, 2015 at 17:48

1 Answer 1

5

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.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.