Reputation: 33
I want to check, that users table records does not have specific email already stored.
If there is, then ModelState.IsValid
returns false in controller action.
I understand need of unique constraint and I understand issues with race conditions. Those are not my concern right now.
At this point I just want to make ModelState.IsValid
to return false after querying data in right place and making model invalid.
Should I implement such validation:
DbContext
?SomeCustomValidation
class?And nice bonus would be create solution reusable across all entities :)
How should I do it?
Upvotes: 3
Views: 3372
Reputation: 36645
You can custom validation attribute like below:
public class TestEmailAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
var context = (YourDbContext)validationContext.GetService(typeof(YourDbContext));
if(!context.User.Any(a=>a.Email==value.ToString()))
{
return ValidationResult.Success;
}
return new ValidationResult("Email exists");
}
}
Model:
public class User
{
public int Id { get; set; }
[TestEmail]
public string Email { get; set; }
}
View(Test.cshtml):
@model User
<form method="post" asp-action="Test" asp-controller="Home">
<div class="form-group">
<input asp-for="Email" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<input type="submit" value="Post"/>
</form>
Controller:
//GET render the Test.cshtml
public async Task<IActionResult> Test()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Test(User user)
{
if(!ModelState.IsValid)
{
return View(user);
}
return RedirectToAction("Index");
}
Upvotes: 4
Reputation: 197
better way is that you check it before every insert or update by :
if(db.Table.Any(x => x.UniqueCloumn == newValue))
error = "this record is already exist"
else
{
db.Table.Add(newObject);
db.Savechanges()
}
also there is some approach for reusable code that I do not recommend : https://www.codeproject.com/Tips/1143215/Validate-a-Unique-Constraint-at-dbContext-Validate
Upvotes: 0