5

In ASP.Net MVC 5 View we have an automatic error message popped-up when a control/input in the View tries to create column value in the database (or a field value in a class) which is supposed to be unique but we violate it - such as when creating new user account's email with an already existing email as shown below.

enter image description here

Now, I am supposed to change the error message above into a local language in my project:

... is already taken <-> ... [is already taken in local language]

How to change the "[field value] already taken" (automatic) error message?

According to this post:

Issue with username validation message in asp.net identity

We could just try to search for "Name {0} is already taken" in the whole solution, but when I did that, I couldn't find it.

enter image description here

Was that a valid solution in earlier MVC but outdated for MVC 5?

(Note: unfortunately, the post does not indicate which ASP.Net MVC version the OP is working with)

dbc
  • 104,963
  • 20
  • 228
  • 340
Ian
  • 30,182
  • 19
  • 69
  • 107
  • did you try with `DataAnnotations` ? – Sunil Kumar Aug 10 '16 at 12:12
  • @SunilKumar Nope. Mind to give an example if you know how? In the end, I have not-so-general solution for this by intercepting the error message just before it is thrown to the `View` and change it. It works, but definitely is not a good idea for more error messages. :/ would appreciate if you know better solution. – Ian Aug 10 '16 at 12:14
  • Are you using `Asp.Net Identity` or `MembershipProvider`? – trailmax Aug 10 '16 at 13:14

4 Answers4

4

I have implemented this via using Remote in System.ComponentModel.DataAnnotations. Please refer following code :

In ViewModel (Properties) :

        [Display(Name = "Email")]
        [Remote("IsValidUserName", "Remote", AdditionalFields = "Email", HttpMethod = "Post")]
        public string Email { get; set; }

Here "Remote" is a Controller Name and "IsValidUserName" our Method. Like below:

public class RemoteController : Controller
    {
        [AcceptVerbs(HttpVerbs.Post)]
        public JsonResult IsValidUserName()
        {
            string email= Request.Form["Email"];  
            string message = "Email '"+ email+ "' is already taken";
            if (!string.IsNullOrEmpty(email))
            {
                using (DbContext db = new DbContext())
                {
                    if (!db.tb_Users.Any(x => x.email== email))
                    {
                        message = string.Empty;
                    }
                }
            }
            if (message == string.Empty)
                return Json(true, JsonRequestBehavior.AllowGet);
            else
                return Json(message, JsonRequestBehavior.AllowGet);
        }
}

and on View page you have to use this like below:

 @Html.TextBoxFor(model => model.Email)
 @Html.ValidationMessageFor(model => model.Email)

Output will be : enter image description here

Points to remember: You have to use following JavaScripts for running this:

<script   src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script   src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.min.jss"></script>
<script   src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"></script>

Hope it helps you.

Thanks.

Sunil Kumar
  • 3,142
  • 1
  • 19
  • 33
  • Hi Sunil, thanks for the given answer. I will check it out. You got my upvote anyway. ;) – Ian Aug 10 '16 at 13:32
2

A quick and a bit hacky solution to this would be:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = UserRepo.CreateUser(model.Email, model.Password);
            if (!result.Succeeded)
            {
                 AddErrors(result);
            }
        }
    }



    private void AddErrors(IdentityResult result)
    {
        foreach (var error in result.Errors)
        {
            string errorMessage = error;
            if (error.EndsWith("is already taken."))
                errorMessage = "Your error message";
            ModelState.AddModelError("", errorMessage);
        }
    }
Sgedda
  • 1,323
  • 1
  • 18
  • 27
1

As someone answered. I am correcting something.

In your Account controller, find the following class and changes like this.

private void AddErrors(IdentityResult result)
        {
            foreach (var error in result.Errors)
            {

                string errorMessage = error;
                if (error.EndsWith("is already taken."))
                {
                    errorMessage = "This email id is alreday registered !";
                    ModelState.AddModelError("", errorMessage);
                    break;
                }

                ModelState.AddModelError("", error);
            }
        }
-1

In your model class try do it with data annotiations by adding following line before your property:

[Required(ErrorMessage = "is already taken in local language")]

You can install .NET Framework with your language pack if it is possible. Then you will have all error messages in local language.

zmierzlik
  • 17
  • 3
  • I have already done it, but that changes the "Field is required" error message instead of "is already taken" error message. There are two different error messages here: "is required" and "is already taken" – Ian Aug 10 '16 at 09:42