asp.net-mvc-3

ASP.Net MVC 3 JSON Model Binding y validación del modelo del lado del servidor combinados con la validación del lado del cliente



asp.net-mvc-3 (3)

He estado jugando con el nuevo MVC3 Json Model Binding y es bastante bueno.

Actualmente, puedo publicar JSON en el controlador y enlazarlo. La validación del modelo ocurre muy bien también.

¿Pero qué pasa si el modelo no es válido?

Me gustaría devolver JSON y que el lado del cliente notifique al usuario (por ejemplo, cómo realizaría la validación del lado del cliente normal en mvc)

¿Alguien sabe de algunos tutoriales sobre cómo realizar esto?

¿Es esto posible?

¿O hay marcos que puedo aprovechar para hacer esto?


@Junto y @ Jamey777, ambos pasan el ModelState a su función de error, pero luego usan la variable global en lugar del parámetro.

y ¿por qué no usas un poco de linq como

private Dictionary<string, string> GetModelStateErrorsAsString() { return ModelState.Where(x=> x.Value.Errors.Any()) .ToDictionary(x => x.Key, x => x.Value.Errors.First().ErrorMessage); }


Gracias por esta solución. Lo mejoré un poco al pasar un diccionario para que pueda utilizar el javascript discreto para poner la validación en los campos individuales en lugar de un resumen haciendo referencia a la clave del diccionario.

private Dictionary<string, string> GetModelStateErrorsAsString(ModelStateDictionary state) { Dictionary<string, string> errors = new Dictionary<string, string>(); foreach (var key in ModelState.Keys) { var error = ModelState[key].Errors.FirstOrDefault(); if (error != null) { errors.Add(key, error.ErrorMessage); } } return errors; }


El siguiente ejemplo funciona para mí cuando utilizo JavaScript discreto en MVC3. Estoy haciendo algo muy similar. Dada la siguiente clase JsonResponse :

public enum Status { Ok, Error } public class JsonResponse { public Status Status { get; set; } public string Message { get; set; } public List<string> Errors { get; set; } }

Mi controlador puede tener un método así:

[HttpPost] public ActionResult Login(UserLoginModel model) { JsonResponse res = new JsonResponse(); if (!ModelState.IsValid) { res.Status = Status.Error; res.Errors = GetModelStateErrorsAsString(this.ModelState); res.Message = "Oh dear, what have you done. Check the list of errors dude!"; } else { // Save it here... // Return success res.Status = Status.Ok; res.Message = "Everything was hunky dory"; } return Json(res); }

Y el ModelStateDictionary se puede enumerar para los errores así:

private List<string> GetModelStateErrorsAsString(ModelStateDictionary state) { List<string> errors = new List<string>(); foreach (var key in ModelState.Keys) { var error = ModelState[key].Errors.FirstOrDefault(); if (error != null) { errors.Add(error.ErrorMessage); } } return errors; }

Entonces, en mi opinión, puedo tener el siguiente JSON POST:

<script type="text/javascript"> $("form").submit(function (evt) { // validate $(''form'').valid(); // extract values to submit var form = $(this), username = form.find("[name=Username]").val(), password = form.find("[name=Password]").val(), json = JSON.stringify({ Username: username, Password: password }); $.ajax({ url: form.attr("action"), type: ''POST'', contentType: ''application/json; charset=utf-8'', dataType: ''json'', data: json, success: function (result) { alert(result.Message); } }); // stop form submitting evt.preventDefault(); }); </script>

Estoy usando jQuery.tmpl para mostrar los errores. Sin embargo, he excluido eso de este ejemplo.