Asked by:
IdentityResult IdentityError

Question
-
User-399606103 posted
Hi - when creating a user by calling "UserManager.CreateAsync(user, password)", one can receive an error (or several) in the returned IdentityResult.
I want to map these errors to specific input fields on the View (so I can display specific error messages next to the field). It seems though, that at this point, the CreateAsync method doesn't actually know anything about my View's fields, so is this a manual process where I can loop through the Errors, and check the Code value which I can try to map to a specific field?
(Also, of course, it appears some errors may not be related to specific fields - so these general errors can be presented at the top of the form).
Wednesday, March 11, 2020 2:38 PM
All replies
-
User711641945 posted
Hi Argghh,
so is this a manual process where I can loop through the Errors, and check the Code value which I can try to map to a specific field?I think you could try to foreach the IdentityError and judge if the code contains the property name in it like below:
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email }; var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) { //... } foreach (var error in result.Errors) { if(error.Code.Contains("Password")) { ViewData["Password"] = ViewData["Password"]+ error.Description; } else { ModelState.AddModelError(error.Code, error.Description); } } } // If we got this far, something failed, redisplay form return Page(); } }
2.Register.cshtml:
<div class="col-md-4"> <form asp-route-returnUrl="@Model.ReturnUrl" method="post"> <h4>Create a new account.</h4> <hr /> <div asp-validation-summary="All" class="text-danger"></div> <div class="form-group"> <label asp-for="Input.Email"></label> <input asp-for="Input.Email" class="form-control" /> <span asp-validation-for="Input.Email" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Input.Password"></label> <input asp-for="Input.Password" class="form-control" /> <span asp-validation-for="Input.Password" class="text-danger"></span> @if(@ViewData["Password"]!=null) { <span class="text-danger">@ViewData["Password"]</span> } </div> <div class="form-group"> <label asp-for="Input.ConfirmPassword"></label> <input asp-for="Input.ConfirmPassword" class="form-control" /> <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary">Register</button> </form> </div>
Result:
Best Regards,
Rena
Friday, March 13, 2020 9:09 AM -
User-399606103 posted
Thanks for your great answer. I ended up implementing some custom logic (a little like your answer, where I loop through the errors checking the "codes"). My code is pretty specific to my solution (specific fields on the view), but it is good enough for me at the moment. I'd like to make it a better general solution, but that will have to wait...
I found a lot of code from various places on the Web, and spliced it together to implement an extension method for the html-helper, which generates the error-html, based on "keys" I have put in the ModelState.
public static IHtmlContent ValidationMultimessageFor<TModel, TResult>(this IHtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TResult>> expression, object htmlAttributes = null)
So on my view, I can have stuff like:
@Html.ValidationMultimessageFor(m => user.Email, new { @class = "text-danger" })
I put the keys and error-messages in the ModelState in my controller, based on the IdentityErrors I get from calling the Identity-api to create or update a user for example. This is where I have had to loop over the IdentityErrors (and make some assumptions about the fieldnames on the view, because I couldn't work out how to do the mapping in a completely general fashion).
Thanks!
Friday, March 13, 2020 9:38 AM