web-dev-qa-db-fra.com

Méthode MVC ajax json post to controller

J'essaie d'obtenir un appel JQuery AJAX à une méthode d'action de contrôleur qui contient un objet complexe en tant que paramètre .. J'ai lu beaucoup de blogs et essayé plusieurs techniques apprises à partir de ceux-ci. Le message clé sur lequel j'ai construit mon meilleur code de tentative (ci-dessous) est le message stackoverflow ici .

Je souhaite déclencher une publication asynchrone, appelée lorsque l'utilisateur sélectionne un champ [pas une publication de formulaire -, comme illustré dans d'autres exemples que j'ai trouvés]. 

Mon intention est de:

  • Instanciez un objet sur le client [pas le ViewModel qui fournit le type pour la vue];
  • Remplissez l'objet avec les données de plusieurs champs de la vue;
  • Convertissez cet objet en JSON;
  • Appelez la méthode d'action du contrôleur à l'aide de la méthode jQuery.Ajax, en transmettant l'objet JSON.

Les résultats seront renvoyés sous forme de résultat JSON. et les données seront chargées dans les champs de la vue en fonction des résultats renvoyés.

Les problèmes sont: 

  • Si la méthode d’action est attribuée à l’attribut HttpPost, la méthode d’action du contrôleur n’est pas appelée (même si le type d’appel AJAX est défini sur ‘POST’) .
  • Si la méthode d'action est attribuée avec HttpGet, les valeurs des propriétés du paramètre sont null
  • La méthode ReadObject génère l'erreur suivante: "Élément attendu" racine "de l'espace de noms" ".." Aucun "rencontré" avec le nom "espace de nom" ".

J'espère que quelqu'un pourra vous aider. Merci. Code ci-dessous:

Fichier js client

 var disputeKeyDataObj = {
     "InvoiceNumber": "" + $.trim(this.value) + "",
     "CustomerNumber": "" + $.trim($('#CustomerNumber').val()) + ""
  };

  var disputeKeyDataJSON = JSON.stringify(disputeHeadlineData);      

  $.ajax({
     url: "/cnr/GetDataForInvoiceNumber",
     type: "POST",
     data: disputeKeyDataJSON,
     dataType: 'json',
     contentType: "application/json; charset=utf-8",
     success: EnrichedDisputeKeyData(result)
  });


Action Filtre et classe pour le type associé au paramètre de méthode Action 

 [DataContract]  
 public class DisputeKeyData  
 {  
    [DataMember(Name = "InvoiceNumber")]  
    public string InvoiceNumber { get; set; }

    [DataMember(Name = "CustomerNumber")]
    public string CustomerNumber { get; set; }
 }  

Méthode d'action sur le contrôleur 

  //[HttpPost]
  [ObjectFilter(Param = "disputeKeyData", RootType = typeof(DisputeKeyData))]  
  public ActionResult GetDataForInvoiceNumber(DisputeKeyData disputeKeyData)  
  {  
     //Blah!  
     //....  
     return Json(disputeKeyData, JsonRequestBehavior.AllowGet);  
  }  
32
Grant Sutcliffe

Voici comment cela fonctionne. 

Le point clé était: Je devais utiliser le ViewModel associé à la vue pour que le moteur d'exécution puisse résoudre l'objet dans la demande. 

[Je sais qu'il existe un moyen de lier un objet autre que l'objet ViewModel par défaut, mais que j'ai fini par renseigner simplement les propriétés nécessaires à mes besoins, car je ne pouvais pas le faire fonctionner]

[HttpPost]  
  public ActionResult GetDataForInvoiceNumber(MyViewModel myViewModel)  
  {            
     var invoiceNumberQueryResult = _viewModelBuilder.HydrateMyViewModelGivenInvoiceDetail(myViewModel.InvoiceNumber, myViewModel.SelectedCompanyCode);
     return Json(invoiceNumberQueryResult, JsonRequestBehavior.DenyGet);
  }

Le script JQuery utilisé pour appeler cette méthode d'action:

var requestData = {
         InvoiceNumber: $.trim(this.value),
         SelectedCompanyCode: $.trim($('#SelectedCompanyCode').val())
      };


      $.ajax({
         url: '/en/myController/GetDataForInvoiceNumber',
         type: 'POST',
         data: JSON.stringify(requestData),
         dataType: 'json',
         contentType: 'application/json; charset=utf-8',
         error: function (xhr) {
            alert('Error: ' + xhr.statusText);
         },
         success: function (result) {
            CheckIfInvoiceFound(result);
         },
         async: true,
         processData: false
      });
35
Grant Sutcliffe

Ce blog post adresse directement votre problème.

Il utilise une technique sans avoir besoin de bibliothèques client JSON supplémentaires. Il introduit un plugin très simple jQuery qui vous aidera à faire le tour.

4
Robert Koritnik

Quelle version de asp.net mvc utilisez-vous? La publication d'objets JSON sur des actions de contrôleur fortement typées vient d'être ajoutée à ASP.NET MVC 3 Beta 1. Cet article explique une solution de contournement utilisant des classeurs de modèle pour asp.net mvc 2 et des informations sur son fonctionnement dans MVC 3.

0
bkaid