tags:

views:

70

answers:

2

How can I display modelstate errors returned by Json ?

I want to do somthing like that...

 if (!ValidateLogOn(Name, currentPassword))
            {
                ModelState.AddModelError("_FORM", "Username or password is incorrect.");

                 //Return a json object to the javascript
                return Json(new { ModelState });
            }

What must be my code in the view to read the modelstate errors and display them?

My actual code in the view is as follows to read the Json values:

function createCategoryComplete(e) { 
var obj = e.get_object(); 
alert(obj.Values); 

}

A: 

If you are returning JSON, you cannot use ModelState. Everything that the view needs should be contained inside the JSON string. So instead of adding the error to the ModelState you could add it to the model you are serializing:

public ActionResult Index()
{
    return Json(new 
    {
        errorControl = "_FORM",
        errorMessage = "Username or password is incorrect.",
        someOtherProperty = "some other value"
    });
}
Darin Dimitrov
Don't see why ModelState can't be used. E.g. model binders can put errors to ModelState, action filters, etc; if we don't use ModelState user won't even know about them.
queen3
A: 

This is draft code but the same idea works for me in production. The main idea here is that Json errors have predefined tag names, that no normal objects will have. For errors validation errors HTML is re-created using JavaScript (both top summary and form elements highlighting).

Server side:

  public static JsonResult JsonValidation(this ModelStateDictionary state)
  {
     return new JsonResult
     {
        Data = new
           {
              Tag = "ValidationError",
              State = from e in state
                      where e.Value.Errors.Count > 0
                      select new
                      {
                         Name = e.Key,
                         Errors = e.Value.Errors.Select(x => x.ErrorMessage)
                            .Concat(e.Value.Errors.Where(x => x.Exception != null).Select(x => x.Exception.Message))
                      }
           }
     };
  }

  in action:
  if (!ModelState.IsValid && Request.IsAjaxRequest())
      return ModelState.JsonValidation();

Client side:

function getValidationSummary() {
   var el = $(".validation-summary-errors");
   if (el.length == 0) {
      $(".title-separator").after("<div><ul class='validation-summary-errors ui-state-error'></ul></div>");
      el = $(".validation-summary-errors");
   }
   return el;
}

function getResponseValidationObject(response) {
   if (response && response.Tag && response.Tag == "ValidationError")
      return response;
   return null;
}

function CheckValidationErrorResponse(response, form, summaryElement) {
   var data = getResponseValidationObject(response);
   if (!data) return;

   var list = summaryElement || getValidationSummary();
   list.html('');
   $.each(data.State, function(i, item) {
      list.append("<li>" + item.Errors.join("</li><li>") + "</li>");
      if (form && item.Name.length > 0)
         $(form).find("*[name='" + item.Name + "']").addClass("ui-state-error");
   });
}

$.ajax(... function(response) { 
   CheckValidationErrorResponse(xhr.responseText); } );
queen3