Utilisez la validation ASP.NET MVC avec jquery ajax?

J’ai une simple action ASP.NET MVC comme ceci:

public ActionResult Edit(EditPostViewModel data) { } 

Le EditPostViewModel a des atsortingbuts de validation comme ceci:

 [Display(Name = "...", Description = "...")] [SsortingngLength(100, MinimumLength = 3, ErrorMessage = "...")] [Required()] public ssortingng Title { get; set; } 

Dans la vue, j’utilise les aides suivantes:

  @Html.LabelFor(Model => Model.EditPostViewModel.Title, true) @Html.TextBoxFor(Model => Model.EditPostViewModel.Title, new { @class = "tb1", @Style = "width:400px;" }) 

Si je fais un envoi sur un formulaire que cette zone de texte est placée dans une validation sera d’abord effectuée sur le client, puis sur le service ( ModelState.IsValid ).

Maintenant, j’ai quelques questions:

  1. Peut-on utiliser jQuery ajax submit à la place? Ce que je fais est simplement de supprimer le formulaire et en cliquant sur le bouton soumettre, un javascript rassemblera les données et exécutera le $.ajax .

  2. Est-ce que le côté serveur ModelState.IsValid fonctionne?

  3. Comment puis-je renvoyer le problème de validation au client et le présenter comme si Im utilisait la validation de construction int ( @Html.ValidationSummary(true) )?

Exemple d’appel Ajax:

 function SendPost(actionPath) { $.ajax({ url: actionPath, type: 'POST', dataType: 'json', data: { Text: $('#EditPostViewModel_Text').val(), Title: $('#EditPostViewModel_Title').val() }, success: function (data) { alert('success'); }, error: function () { alert('error'); } }); } 

Edit 1:

Inclus à la page:

    

Côté client

Utiliser la bibliothèque jQuery.validate devrait être assez simple à configurer.

Spécifiez les parameters suivants dans votre fichier Web.config :

     

Lorsque vous construisez votre vue, vous définissez des choses comme ceci:

 @Html.LabelFor(Model => Model.EditPostViewModel.Title, true) @Html.TextBoxFor(Model => Model.EditPostViewModel.Title, new { @class = "tb1", @Style = "width:400px;" }) @Html.ValidationMessageFor(Model => Model.EditPostViewModel.Title) 

REMARQUE: ces éléments doivent être définis dans un élément de formulaire

Ensuite, vous devez inclure les bibliothèques suivantes:

   

Cela devrait être en mesure de vous configurer pour la validation côté client

Ressources

Du côté serveur

REMARQUE: Ceci est uniquement pour la validation côté serveur supplémentaire en haut de la bibliothèque jQuery.validation

Peut-être que quelque chose comme ça pourrait aider:

 [ValidateAjax] public JsonResult Edit(EditPostViewModel data) { //Save data return Json(new { Success = true } ); } 

ValidateAjax est un atsortingbut défini comme:

 public class ValidateAjaxAtsortingbute : ActionFilterAtsortingbute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest()) return; var modelState = filterContext.Controller.ViewData.ModelState; if (!modelState.IsValid) { var errorModel = from x in modelState.Keys where modelState[x].Errors.Count > 0 select new { key = x, errors = modelState[x].Errors. Select(y => y.ErrorMessage). ToArray() }; filterContext.Result = new JsonResult() { Data = errorModel }; filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.BadRequest; } } } 

Cela renvoie un object JSON spécifiant toutes les erreurs de votre modèle.

Exemple de réponse serait

 [{ "key":"Name", "errors":["The Name field is required."] }, { "key":"Description", "errors":["The Description field is required."] }] 

Cela serait retourné à votre erreur de gestion du rappel de l’appel $.ajax

Vous pouvez parcourir les données renvoyées pour définir les messages d’erreur en fonction des clés renvoyées (je pense que quelque chose comme $('input[name="' + err.key + '"]') trouverait votre élément d’entrée

Ce que vous devez faire est de sérialiser les données de votre formulaire et de l’envoyer à l’action du contrôleur. ASP.NET MVC liera les données de formulaire à l’object EditPostViewModel (votre paramètre de méthode d’action) à l’aide de la fonctionnalité de liaison de modèle MVC.

Vous pouvez valider votre formulaire côté client et, si tout va bien, envoyer les données au serveur. La méthode valid() sera utile.

 $(function () { $("#yourSubmitButtonID").click(function (e) { e.preventDefault(); var _this = $(this); var _form = _this.closest("form"); var isvalid = _form .valid(); // Tells whether the form is valid if (isvalid) { $.post(_form.attr("action"), _form.serialize(), function (data) { //check the result and do whatever you want }) } }); }); 

Voici une solution plutôt simple:

Dans le contrôleur, nous renvoyons nos erreurs comme ceci:

 if (!ModelState.IsValid) { return Json(new { success = false, errors = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).ToList() }, JsonRequestBehavior.AllowGet); } 

Voici quelques exemples de script client:

 function displayValidationErrors(errors) { var $ul = $('div.validation-summary-valid.text-danger > ul'); $ul.empty(); $.each(errors, function (idx, errorMessage) { $ul.append('
  • ' + errorMessage + '
  • '); }); }

    Voilà comment nous le traitons via ajax:

     $.ajax({ cache: false, async: true, type: "POST", url: form.attr('action'), data: form.serialize(), success: function (data) { var isSuccessful = (data['success']); if (isSuccessful) { $('#partial-container-steps').html(data['view']); initializePage(); } else { var errors = data['errors']; displayValidationErrors(errors); } } }); 

    De plus, je rend des vues partielles via ajax de la manière suivante:

     var view = this.RenderRazorViewToSsortingng(partialUrl, viewModel); return Json(new { success = true, view }, JsonRequestBehavior.AllowGet); 

    Méthode RenderRazorViewToSsortingng:

     public ssortingng RenderRazorViewToSsortingng(ssortingng viewName, object model) { ViewData.Model = model; using (var sw = new SsortingngWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); return sw.GetSsortingngBuilder().ToSsortingng(); } } 

    Vous pouvez le faire de cette façon:

    ( Edit: Considérant que vous attendez une réponse json avec dataType: 'json' )

    .NET

     public JsonResult Edit(EditPostViewModel data) { if(ModelState.IsValid) { // Save return Json(new { Ok = true } ); } return Json(new { Ok = false } ); } 

    JS:

     success: function (data) { if (data.Ok) { alert('success'); } else { alert('problem'); } }, 

    Si vous en avez besoin, je peux également vous expliquer comment le faire en renvoyant une erreur 500 et obtenir l’erreur dans l’erreur d’événement (ajax). Mais dans votre cas, cela peut être une option

    Ajout d’une logique supplémentaire à la solution fournie par @Andrew Burgess. Voici la solution complète:

    Création d’un filtre d’action pour obtenir des erreurs pour une requête ajax:

     public class ValidateAjaxAtsortingbute : ActionFilterAtsortingbute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest()) return; var modelState = filterContext.Controller.ViewData.ModelState; if (!modelState.IsValid) { var errorModel = from x in modelState.Keys where modelState[x].Errors.Count > 0 select new { key = x, errors = modelState[x].Errors. Select(y => y.ErrorMessage). ToArray() }; filterContext.Result = new JsonResult() { Data = errorModel }; filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; } } } 

    Ajout du filtre à ma méthode de contrôleur en tant que:

     [HttpPost] // this line is important [ValidateAjax] public ActionResult AddUpdateData(MyModel model) { return Json(new { status = (result == 1 ? true : false), message = message }, JsonRequestBehavior.AllowGet); } 

    Ajout d’un script commun pour la validation de jquery:

     function onAjaxFormError(data) { var form = this; var errorResponse = data.responseJSON; $.each(errorResponse, function (index, value) { // Element highlight var element = $(form).find('#' + value.key); element = element[0]; highLightError(element, 'input-validation-error'); // Error message var validationMessageElement = $('span[data-valmsg-for="' + value.key + '"]'); validationMessageElement.removeClass('field-validation-valid'); validationMessageElement.addClass('field-validation-error'); validationMessageElement.text(value.errors[0]); }); } $.validator.setDefaults({ ignore: [], highlight: highLightError, unhighlight: unhighlightError }); var highLightError = function(element, errorClass) { element = $(element); element.addClass(errorClass); } var unhighLightError = function(element, errorClass) { element = $(element); element.removeClass(errorClass); } 

    Enfin ajouté la méthode javascript d’erreur à mon formulaire Ajax Begin:

     @model My.Model.MyModel @using (Ajax.BeginForm("AddUpdateData", "Home", new AjaxOptions { HttpMethod = "POST", OnFailure="onAjaxFormError" })) { }