ASP.NET MVC How to convert ModelState errors to json

前端 未结 13 2052
余生分开走
余生分开走 2020-12-04 05:24

How do you get a list of all ModelState error messages? I found this code to get all the keys: ( Returning a list of keys with ModelState errors)

var errorK         


        
相关标签:
13条回答
  • 2020-12-04 05:34

    Simple way achieve this by using built-in functionality

    [HttpPost]
    public IActionResult Post([FromBody]CreateDoctorInput createDoctorInput) {
        if (!ModelState.IsValid) {
            return BadRequest(ModelState);
        }
    
        //do something
    }
    

    JSON result will be

    0 讨论(0)
  • 2020-12-04 05:37

    I made and extension that returns string with seperator " " (you can use your own):

       public static string GetFullErrorMessage(this ModelStateDictionary modelState) {
            var messages = new List<string>();
    
            foreach (var entry in modelState) {
                foreach (var error in entry.Value.Errors)
                    messages.Add(error.ErrorMessage);
            }
    
            return String.Join(" ", messages);
        }
    
    0 讨论(0)
  • 2020-12-04 05:39

    I like to use Hashtable here, so that I get JSON object with properties as keys and errors as value in form of string array.

    var errors = new Hashtable();
    foreach (var pair in ModelState)
    {
        if (pair.Value.Errors.Count > 0)
        {
            errors[pair.Key] = pair.Value.Errors.Select(error => error.ErrorMessage).ToList();
        }
    }
    return Json(new { success = false, errors });
    

    This way you get following response:

    {
       "success":false,
       "errors":{
          "Phone":[
             "The Phone field is required."
          ]
       }
    }
    
    0 讨论(0)
  • 2020-12-04 05:41

    Here is the full implementation with all the pieces put together:

    First create an extension method:

    public static class ModelStateHelper
    {
        public static IEnumerable Errors(this ModelStateDictionary modelState)
        {
            if (!modelState.IsValid)
            {
                return modelState.ToDictionary(kvp => kvp.Key,
                    kvp => kvp.Value.Errors
                                    .Select(e => e.ErrorMessage).ToArray())
                                    .Where(m => m.Value.Any());
            }
            return null;
        }
    }
    

    Then call that extension method and return the errors from the controller action (if any) as json:

    if (!ModelState.IsValid)
    {
        return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
    }
    

    And then finally, show those errors on the clientside (in jquery.validation style, but can be easily changed to any other style)

    function DisplayErrors(errors) {
        for (var i = 0; i < errors.length; i++) {
            $("<label for='" + errors[i].Key + "' class='error'></label>")
            .html(errors[i].Value[0]).appendTo($("input#" + errors[i].Key).parent());
        }
    }
    
    0 讨论(0)
  • 2020-12-04 05:42

    @JK it helped me a lot but why not:

     public class ErrorDetail {
    
            public string fieldName = "";
            public string[] messageList = null;
     }
    

            if (!modelState.IsValid)
            {
                var errorListAux = (from m in modelState 
                         where m.Value.Errors.Count() > 0 
                         select
                            new ErrorDetail
                            { 
                                    fieldName = m.Key, 
                                    errorList = (from msg in m.Value.Errors 
                                                 select msg.ErrorMessage).ToArray() 
                            })
                         .AsEnumerable()
                         .ToDictionary(v => v.fieldName, v => v);
                return errorListAux;
            }
    
    0 讨论(0)
  • 2020-12-04 05:45

    The easiest way to do this is to just return a BadRequest with the ModelState itself:

    For example on a PUT:

    [HttpPut]
    public async Task<IHttpActionResult> UpdateAsync(Update update)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
    
        // perform the update
    
        return StatusCode(HttpStatusCode.NoContent);
    }
    

    If we use data annotations on e.g. a mobile number, like this, in the Update class:

    public class Update {
        [StringLength(22, MinimumLength = 8)]
        [RegularExpression(@"^\d{8}$|^00\d{6,20}$|^\+\d{6,20}$")]
        public string MobileNumber { get; set; }
    }
    

    This will return the following on an invalid request:

    {
      "Message": "The request is invalid.",
      "ModelState": {
        "update.MobileNumber": [
          "The field MobileNumber must match the regular expression '^\\d{8}$|^00\\d{6,20}$|^\\+\\d{6,20}$'.",
          "The field MobileNumber must be a string with a minimum length of 8 and a maximum length of 22."
        ]
      }
    }
    
    0 讨论(0)
提交回复
热议问题