Validation message don´t receive the error from Controller

Viewed 293

I have the error passing throw the API to the Controller and after i show on view, but i just can show on ValidationSummary. How i show to the ValidationMessageFor ?

I have this in my Model:

public class User
{
    [Required(ErrorMessage="Username is Required",AllowEmptyStrings=false)]
    [MinLength(10, ErrorMessage = "Name cannot be less than 10")]
    [MaxLength(20, ErrorMessage = "Name cannot be higher than 20")]
    public string Name{get; set;}
}

And this in my MVC Controller:

[HttpPost]
    public async Task<ActionResult> create(User user)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("https://localhost:5000/api/users/");

            //HTTP POST
            var response = await client.PostAsJsonAsync<User>("create",user);

            var response_api = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode)
            {
                return RedirectToAction("Index");
            }
            else
            {
                ModelState.AddModelError(string.Empty, response_api.ToString());
            }
        }
        return View(user);
    }

Where i'm returning the response from api in ModelState.AddModelError(string.Empty, response_api.ToString());

but the response just has sent to the @Html.ValidationSummary(true, "", new { @class = "text-danger" }) and not for the correspondent @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }), why? what i can do to this work? and one more question, is normal the response from DataAnnotations return me this error:

{"type":"https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|fdb6e77c-4d37747fda3a69c9.1.6cd6fd5a_","errors":{"Name":["Username is Required"]}}

and not just the Username is Required.

1 Answers

The first parameter in ModelState.AddModelError identifies the Property name in the Model on which bind the error to.

While it is possibile for you to parse PostAsJsonAsync response and bind each error to the correct property, calling your underlying API without validating input model first is not a best practice, though.

I suggest you change your code into something like this:

    [HttpPost]
    public async Task<ActionResult> create(User user)
    {
        If(ModelState.IsValid)
        {
           using (var client = new HttpClient())
           {
              client.BaseAddress = new Uri("https://localhost:5000/api/users/");

              //HTTP POST
              var response = await client.PostAsJsonAsync<User>("create",user);

              var response_api = await response.Content.ReadAsStringAsync();

              if (response.IsSuccessStatusCode)
              {
                 return RedirectToAction("Index");
              }
              else
              {
                 ModelState.AddModelError(string.Empty, response_api.ToString());
              }
           }
       }
       return View(user);
    }
Related