Reputation: 994
Is there any option to do something like:
[Required(ErrorMessage = "This field is required.")]
public string Name { get; set; }
For:
[Index(IsUnique = true)]
public string Name { get; set; }
The problem is that I would like to show user a validation message if he is trying to duplicate Name property to database by using:
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
Upvotes: 2
Views: 1842
Reputation: 49261
In order to do that using client side validation you need to make an AJAX call to query the database and check that the name is unique. You still need server side validation to catch the unique constraint violation that occurs if the system attempts to insert a duplicate name because a duplicate name may be created between the time you check and the insert is attempted.
I don't attempt to handle this on the client side, I only do it on the server side. Assuming the action is called CreateUser, here's how to handle this in a try-catch block in the post action:
try
{
// create object and save changes
// EF will be throw a DbUpdateException if the insert fails
// redirect to action
}
catch (DbUpdateException ex)
{
if (ExceptionHelper.IsUniqueConstraintViolation(ex))
{
ModelState.AddModelError("Name", $"The Name '{viewModel.Name}' is already in use, please enter a different name.");
return View(nameof(CreateUser), viewModel);
}
}
The exception detection is database specific, this is for SQL Server:
public static class ExceptionHelper
{
private static Exception GetInnermostException(Exception ex)
{
while (ex.InnerException != null)
{
ex = ex.InnerException;
}
return ex;
}
public static bool IsUniqueConstraintViolation(Exception ex)
{
var innermost = GetInnermostException(ex);
var sqlException = innermost as SqlException;
return sqlException != null && sqlException.Class == 14 && (sqlException.Number == 2601 || sqlException.Number == 2627);
}
}
If users are persistent and keep trying to use the same name, you could return the previously attempted name in the view model and do client side validation to prevent re-tries.
Upvotes: 1