web-dev-qa-db-fra.com

Enregistrement de données JSON via jQuery sur ASP Action du contrôleur .NET MVC 4

Je ne parviens pas à passer un objet JSON complexe à une action du contrôleur MVC 4. Le contenu JSON étant variable, je ne souhaite pas que MVC mappe des propriétés/éléments individuels du JSON avec des paramètres de la liste de paramètres de la méthode d'action. Je veux juste obtenir les données en tant que paramètre de chaîne JSON unique dans l'action du contrôleur.

Voici la signature de ma méthode d'action:

    [HttpPost]
    [ValidateInput(false)]
    public string ConvertLogInfoToXml(string jsonOfLog)

Et voici ma tentative de publication de données JSON à partir de mon navigateur:

    data = {prop: 1, myArray: [1, "two", 3]}; 
    //'data' is much more complicated in my real application
    json = {jsonOfLog: data};

    $.ajax({
        type: 'POST',
        url: "Home/ConvertLogInfoToXml",
        data: JSON.stringify(json),
        success: function (returnPayload) {
            console && console.log ("request succeeded");
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console && console.log ("request failed");
        },
        dataType: "xml",
        contentType: "application/json",            
        processData: false,
        async: false
    });

Lorsque je frappe mon point d'arrêt au début de la méthode ConvertLogInfoToXML, jsonOfLog est null.

Si je change la valeur de la variable 'json' dans JavaScript, la propriété jsonOfLog sera une simple chaîne, par exemple. :

json = { jsonOfLog: "simple string" };

puis, lorsque mon point d'arrêt au début de la méthode ConvertLogInfoToXML est atteint, jsonOfLog est la valeur de la chaîne (par exemple, "chaîne simple").

J'ai essayé de changer le type du paramètre jsonOfLog dans la méthode d'action pour qu'il soit de type objet:

    [HttpPost]
    [ValidateInput(false)]
    public string ConvertLogInfoToXml(object jsonOfLog)

Maintenant, avec le code JavaScript original (où je passe un objet 'data' plus complexe), jsonOfLog obtient la valeur de {object}. Mais le débogueur n'affiche pas plus de détails dans une fenêtre de surveillance, et je ne sais pas quelles méthodes je peux utiliser pour utiliser cette variable.

Comment puis-je transmettre des données JSON à un contrôleur MVC, où les données transmises sont un objet complexe stringifié?

Merci, Notre

28
Notre

Le problème est votre dataType et le format de votre paramètre data. Je viens de tester cela dans un bac à sable et les travaux suivants:

C #

    [HttpPost]
    public string ConvertLogInfoToXml(string jsonOfLog)
    {
        return Convert.ToString(jsonOfLog);
    }

javascript

<input type="button" onclick="test()"/>

    <script type="text/javascript">

        function test() {
            data = { prop: 1, myArray: [1, "two", 3] };
            //'data' is much more complicated in my real application
            var jsonOfLog = JSON.stringify(data);

            $.ajax({
                type: 'POST',
                dataType: 'text',
                url: "Home/ConvertLogInfoToXml",
                data: "jsonOfLog=" + jsonOfLog,
                success: function (returnPayload) {
                    console && console.log("request succeeded");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console && console.log("request failed");
                },

                processData: false,
                async: false
            });
        }

    </script>

Faites particulièrement attention à data, lors de l'envoi de texte, vous devez envoyer une variable correspondant au nom de votre paramètre. Ce n'est pas joli, mais cela vous donnera votre chaîne non formatée convoitée.

JsonOfLog ressemble à ceci dans la fonction serveur:

    jsonOfLog   "{\"prop\":1,\"myArray\":[1,\"two\",3]}"    string

L'en-tête HTTP POST:

Key Value
Request POST /Home/ConvertLogInfoToXml HTTP/1.1
Accept  text/plain, */*; q=0.01
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With    XMLHttpRequest
Referer http://localhost:50189/
Accept-Language en-US
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host    localhost:50189
Content-Length  42
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache
Cookie  EnableSSOUser=admin

Le corps HTTP POST:

jsonOfLog={"prop":1,"myArray":[1,"two",3]}

L'en-tête de réponse:

Key Value
Cache-Control   private
Content-Type    text/html; charset=utf-8
Date    Fri, 28 Jun 2013 18:49:24 GMT
Response    HTTP/1.1 200 OK
Server  Microsoft-IIS/8.0
X-AspNet-Version    4.0.30319
X-AspNetMvc-Version 4.0
X-Powered-By    ASP.NET
X-SourceFiles   =?UTF-8?B?XFxwc2ZcaG9tZVxkb2N1bWVudHNcdmlzdWFsIHN0dWRpbyAyMDEyXFByb2plY3RzXE12YzRQbGF5Z3JvdW5kXE12YzRQbGF5Z3JvdW5kXEhvbWVcQ29udmVydExvZ0luZm9Ub1htbA==?=

Le corps de la réponse:

{"prop":1,"myArray":[1,"two",3]}
24
Jaime Torres

VERSION VB.NET

Bon, je viens de passer plusieurs heures à chercher une méthode viable pour publier plusieurs paramètres sur une API Web MVC 4, mais la plupart de ce que j'ai trouvé était soit pour une action 'GET', soit simplement à plat ne fonctionnait pas . Cependant, cela a finalement fonctionné et j'ai pensé partager ma solution. 

  1. Utilisez les packages NuGet pour télécharger JSON-js json2 et Json.NET. Étapes pour installer les paquets NuGet: 

    (1) Dans Visual Studio, accédez à Site Web> Gérer les packages NuGet ... enter image description here

    (2) Tapez json (ou quelque chose de ce genre) dans la barre de recherche et trouvez JSON-js json2 et Json.NET. En double-cliquant dessus, les packages seront installés dans le projet en cours.enter image description here

    (3) NuGet placera automatiquement le fichier json dans ~/Scripts/json2.min.js dans le répertoire de votre projet. Recherchez le fichier json2.min.js et faites-le glisser vers la tête de votre site Web. Note: pour obtenir des instructions sur l'installation de fichiers .js (javascript), lisez cette solution.

  2. Créez un objet de classe contenant les paramètres souhaités. Vous allez l'utiliser pour accéder aux paramètres du contrôleur API. Exemple de code: 

    Public Class PostMessageObj
    
    Private _body As String
    Public Property body As String
        Get
            Return _body
        End Get
        Set(value As String)
            _body = value
        End Set
    End Property
    
    
    Private _id As String
    Public Property id As String
        Get
            Return _id
        End Get
        Set(value As String)
            _id = value
        End Set
    End Property
    End Class
    
  3. Ensuite, nous configurons le contrôleur d’API Web MVC 4 que nous utiliserons pour l’action POST. Dans ce document, nous utiliserons Json.NET pour désérialiser l'objet chaîne lorsqu'il sera publié. N'oubliez pas d'utiliser les espaces de noms appropriés. En reprenant l'exemple précédent, voici mon code:

    Public Sub PostMessage(<FromBody()> ByVal newmessage As String)
    
    Dim t As PostMessageObj = Newtonsoft.Json.JsonConvert.DeserializeObject(Of PostMessageObj)(newmessage)
    
    Dim body As String = t.body
    Dim i As String = t.id
    
    End Sub
    
  4. Maintenant que notre contrôleur d'API est configuré pour recevoir notre objet JSON structuré, nous pouvons appeler l'action POST librement à partir du côté client à l'aide de $ .ajax; En reprenant l'exemple précédent, voici mon code (remplacez localhost + rootpath de manière appropriée):

    var url = 'http://<localhost+rootpath>/api/Offers/PostMessage';
    var dataType = 'json'
    var data = 'nothn'
    var tempdata = { body: 'this is a new message...Ip sum lorem.',
        id: '1234'
    }
    var jsondata = JSON.stringify(tempdata)
    $.ajax({
        type: "POST",
        url: url,
        data: { '': jsondata},
        success: success(data),
        dataType: 'text'
    });
    

Comme vous pouvez le constater, nous sommes en train de construire l'objet JSON, de le convertir en chaîne, de le transmettre sous la forme d'un paramètre unique, puis de le reconstruire via le framework JSON.NET. Je n’ai pas inclus de valeur de retour dans notre contrôleur d’API, je viens donc de placer une valeur de chaîne arbitraire dans la fonction success().


Notes de l'auteur

Cette opération a été effectuée dans Visual Studio 2010 à l'aide d'ASP.NET 4.0, de WebForms, de VB.NET et du contrôleur API Web MVC 4. Si vous rencontrez des problèmes pour intégrer l'API Web MVC 4 à VS2010, vous pouvez télécharger le correctif pour le rendre possible. Vous pouvez le télécharger à partir du Centre de téléchargement de Microsoft

Voici quelques références supplémentaires qui ont aidé (principalement en C #):

2
Lopsided

Je pense que vous trouverez votre réponse si vous vous référez à cet article: Désérialiser JSON en objet dynamique C #?

Il existe différentes façons de réaliser ce que vous voulez ici. L’approche System.Web.Helpers.Json (quelques réponses plus bas) semble être la plus simple.

2
Acorn

// objet json simple dans asp.net mvc

var model = {"Id": "xx", "Name":"Ravi"};
$.ajax({    url: 'test/[ControllerName]',
                        type: "POST",
                        data: model,
                        success: function (res) {
                            if (res != null) {
                                alert("done.");
                            }
                        },
                        error: function (res) {

                        }
                    });


//model in c#
public class MyModel
{
 public string Id {get; set;}
 public string Name {get; set;}
}

//controller in asp.net mvc


public ActionResult test(MyModel model)
{
 //now data in your model 
}
1
Ravi Anand

Eh bien mon côté client (un fichier cshtml) utilisait DataTables pour afficher une grille (maintenant en utilisant le contrôle Infragistics qui sont géniaux) . Et une fois que l'utilisateur a cliqué sur la ligne, j'ai capturé l'événement de ligne et la date associée à cet enregistrement afin de revenir sur le serveur et de faire des demandes supplémentaires côté serveur pour les échanges, etc. .. Et non - je DID ne le stringifie pas ...

Les DataTables ont commencé comme ceci (laissant beaucoup de choses à l’extérieur), et l’événement click est visible ci-dessous, où j’appuie sur mon objet Json:

    oTablePf = $('#pftable').dataTable({         // INIT CODE
             "aaData": PfJsonData,
             'aoColumnDefs': [                     
                { "sTitle": "Pf Id", "aTargets": [0] },
                { "sClass": "**td_nodedate**", "aTargets": [3] }
              ]
              });

   $("#pftable").delegate("tbody tr", "click", function (event) {   // ROW CLICK EVT!! 

        var rownum = $(this).index(); 
        var thisPfId = $(this).find('.td_pfid').text();  // Find Port Id and Node Date
        var thisDate = $(this).find('.td_nodedate').text();

         //INIT JSON DATA
        var nodeDatesJson = {
            "nodedatelist":[]
        };

         // omitting some code here...
         var dateArry = thisDate.split("/");
         var nodeDate = dateArry[2] + "-" + dateArry[0] + "-" + dateArry[1];

         nodeDatesJson.nodedatelist.Push({ nodedate: nodeDate });

           getTradeContribs(thisPfId, nodeDatesJson);     // GET TRADE CONTRIBUTIONS 
    });
0
bob.mazzo

Il y a quelques mois, j'ai rencontré une situation étrange dans laquelle je devais également renvoyer une date au format Json à mon contrôleur. Voici ce que je suis venu après avoir tiré mes cheveux:

Ma classe ressemble à ceci:

public class NodeDate
{
    public string nodedate { get; set; }
}
public class NodeList1
{
    public List<NodeDate> nodedatelist { get; set; }
}

et mon code c # comme suit:

        public string getTradeContribs(string Id, string nodedates)
    {            
        //nodedates = @"{""nodedatelist"":[{""nodedate"":""01/21/2012""},{""nodedate"":""01/22/2012""}]}";  // sample Json format
        System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
        NodeList1 nodes = (NodeList1)ser.Deserialize(nodedates, typeof(NodeList1));
        string thisDate = "";
        foreach (var date in nodes.nodedatelist)
        {  // iterate through if needed...
            thisDate = date.nodedate;
        }   
    }

et ainsi j'ai pu désérialiser mon paramètre d'objet Json nodedates dans l'objet "nœuds"; naturellement bien sûr en utilisant la classe "NodeList1" pour le faire fonctionner.

J'espère que cela aide .... Bob

0
bob.mazzo