Guerrilla Guerrilla - 1 month ago 4
C# Question

How to validate key constraints in ASP.NET MVC

I use the built in model validation which works great for specifying required fields and such but on my model I have specified key constraints so the combination of two columns are unique.

How should I validate for this so it doesn't throw exception if user tries to add duplicate?

Here is my model:

public class EmailFilter
{
public int ID { get; set; }
[Required]
[StringLength(100)]
[Index("IX_FilterAndEmail", 2, IsUnique = true)]
public string Email { get; set; }
//This is an enum
[Required]
[Index("IX_FilterAndEmail", 1, IsUnique = true)]
public EmailFilterType Filter { get; set; }
}


And my create controller method. I tried to add an error but I am not doing it right. It stops the exception happening but it just returns to the listview. I'm not sure what the right way to validate here is.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Email,Filter")] EmailFilter emailFilter)
{
if (ModelState.IsValid)
{
if(db.EmailFilters.Any(x => x.Filter == emailFilter.Filter && x.Email == emailFilter.Email))
{
// This doesn't seem to do anything and returns to listview not create view
// "EFValidationSummary" is the id of my validation summary razor control
ModelState.AddModelError("EFValidationSummary", "This filter already exists");
return View(emailFilter);
}
else
{
db.EmailFilters.Add(emailFilter);
db.SaveChanges();
}

return RedirectToAction("Index");
}

return View(emailFilter);
}


How do I properly trigger an error and send back to the create page with the validation error displayed?

Answer

The first parameter of AddModelError() is the name of the property in your model. In your case, the error message would be displayed in the placeholder generated by

@Html.ValidationMessageFor(m => EFValidationSummary)

but your model does not contain a property named EFValidationSummary. In order to display validation messages in the placeholder generated by @Html.ValidationSummary(), you need to provide an empty string for the first parameter

 ModelState.AddModelError("", "This filter already exists");