Jquery Ajax Posting json to webservice

238

J'essaie de publier un objet JSON sur un service Web asp.net.

Mon json ressemble à ceci:

var markers = { "markers": [
  { "position": "128.3657142857143", "markerPosition": "7" },
  { "position": "235.1944023323615", "markerPosition": "19" },
  { "position": "42.5978231292517", "markerPosition": "-3" }
]};

J'utilise le json2.js pour stringyfy mon objet json.

et j'utilise jquery pour le poster sur mon webservice.

  $.ajax({
        type: "POST",
        url: "/webservices/PodcastService.asmx/CreateMarkers",
        data: markers,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data){alert(data);},
        failure: function(errMsg) {
            alert(errMsg);
        }
  });

Je reçois l'erreur suivante:

"Primitive JSON non valide:

J'ai trouvé un tas de messages à ce sujet et cela semble être un problème vraiment courant, mais rien que j'essaie ne résout le problème.

Lorsque Firebug ce qui est publié sur le serveur, cela ressemble à ceci:

marqueurs% 5B0% 5D% 5Bposition% 5D = 128.3657142857143 & marqueurs% 5B0% 5D% 5BmarkerPosition% 5D = 7 & marqueurs% 5B1% 5D% 5Bposition% 5D = 235.1944023323615 & marqueurs% 5B1% 5D% 5BmarkerPosition% 5D% 5B = 19% 5D = 42,5978231292517 & marqueurs% 5B2% 5D% 5BmarkerPosition% 5D = -3

Ma fonction de service Web appelée est:

[WebMethod]
public string CreateMarkers(string markerArray)
{
    return "received markers";
}
Code Pharaon
la source
«échec» n'est pas fourni comme paramètre possible parmi ceux répertoriés dans api.jquery.com/jQuery.ajax ... peut-être l'avez-vous confondu avec «erreur» à la place?
danicotra

Réponses:

390

Vous avez mentionné l'utilisation de json2.js pour stringifier vos données, mais les données POSTed semblent être JSON URLEncodé Vous l'avez peut-être déjà vu, mais ce post sur la primitive JSON invalide explique pourquoi le JSON est URLEncodé.

Je conseille contre le passage d' une première, chaîne JSON sérialisé manuellement dans votre méthode . ASP.NET va automatiquement désérialiser JSON les données POST de la demande, donc si vous sérialisez et envoyez manuellement une chaîne JSON à ASP.NET, vous finirez par devoir JSON sérialiser votre chaîne sérialisée JSON.

Je suggère quelque chose de plus dans ce sens:

var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },
               { "position": "235.1944023323615", "markerPosition": "19" },
               { "position": "42.5978231292517", "markerPosition": "-3" }];

$.ajax({
    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify({ Markers: markers }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){alert(data);},
    failure: function(errMsg) {
        alert(errMsg);
    }
});

La clé pour éviter le problème de primitive JSON non valide est de transmettre à jQuery une chaîne JSON pour le dataparamètre, pas un objet JavaScript, afin que jQuery n'essaye pas d'URLEncode vos données.

Côté serveur, faites correspondre les paramètres d'entrée de votre méthode à la forme des données que vous transmettez:

public class Marker
{
  public decimal position { get; set; }
  public int markerPosition { get; set; }
}

[WebMethod]
public string CreateMarkers(List<Marker> Markers)
{
  return "Received " + Markers.Count + " markers.";
}

Vous pouvez également accepter un tableau, comme Marker[] Markers, si vous préférez. Le désérialiseur utilisé par ASMX ScriptServices (JavaScriptSerializer) est assez flexible et fera ce qu'il peut pour convertir vos données d'entrée dans le type côté serveur que vous spécifiez.

Dave Ward
la source
4
Vous avez écrit "afin que jQuery n'essaye pas d'URLEncode vos données.", Mais ce n'est pas correct. Pour empêcher jquery de coder en url vos données, vous devez définir processData sur false.
Softlion
8
Passer une chaîne est suffisant pour empêcher jQuery d'URLEncoder le paramètre de données. Vous pouvez définir processData sur false, mais c'est superflu (et le faire seul, sans passer de chaîne JSON pour les données, ne suffit pas).
Dave Ward,
1
Ce même problème (et la même réponse) s'applique également à Rails.
GregT
2
@DaveWard Does contentTypeest-il envisagé si nous utilisons GET et non POST?
Royi Namir
@RoyiNamir Si vous utilisez ASMX ScriptServices ou ASPX WebMethods, vous devez utiliser POST pour obtenir qu'ils retournent JSON. Si vous OBTENEZ, Content-Type correct ou non, vous obtiendrez XML à la place.
Dave Ward
19
  1. markersn'est pas un objet JSON. Il s'agit d'un objet JavaScript normal.
  2. Lisez à propos de l' data:option :

    Données à envoyer au serveur. Il est converti en chaîne de requête , si ce n'est déjà une chaîne.

Si vous souhaitez envoyer les données au format JSON, vous devez d'abord les coder:

data: {markers: JSON.stringify(markers)}

jQuery ne convertit pas automatiquement les objets ou les tableaux en JSON.


Mais je suppose que le message d'erreur provient de l'interprétation de la réponse du service. Le texte que vous renvoyez n'est pas JSON. Les chaînes JSON doivent être placées entre guillemets. Il faudrait donc faire:

return "\"received markers\"";

Je ne sais pas si votre problème réel est l'envoi ou la réception des données.

Felix Kling
la source
Merci pour votre aide Felix, je pensais qu'en exécutant des marqueurs via la méthode JSON.stringyfy je le convertissais en une chaîne de requête, j'ai fait comme vous l'avez suggéré mais malheureusement cela ne fonctionne pas, je ne publie pas ce qui suit.
Code Pharaoh
marqueurs =% 7B% 22marqueurs% 22% 3A% 5B% 7B% 22position% 22% 3A% 22128.3657142857143% 22% 2C% 22markerPosition% 22% 3A% 227% 22% 7D% 2C% 7B% 22position% 22% 3A% 22235.194402332361515 % 22% 2C% 22markerPosition% 22% 3A% 2219% 22% 7D% 2C% 7B% 22position% 22% 3A% 2242.5978231292517% 22% 2C% 22markerPosition% 22% 3A% 22-3% 22% 7D% 5D% 7D
Code Pharaoh
@Dreamguts: Je ne sais pas trop ce que vous voulez. Voulez-vous envoyer en markerstant que chaîne JSON?
Felix Kling
Salut Felix, oui, je veux envoyer l'objet marqueurs sous forme de chaîne JSON afin de pouvoir l'utiliser dans mon service Web.
Code Pharaoh
@Dreamguts: Ensuite, cela devrait fonctionner de cette façon. De plus, le "code" que vous avez publié dans le commentaire semble correct. Bien sûr, vous devez le décoder correctement côté serveur et peut-être devez-vous changer le nom du paramètre, je ne sais pas.
Felix Kling
3

J'ai essayé la solution de Dave Ward. La partie de données n'était pas envoyée par le navigateur dans la partie de la charge utile de la demande de publication, car le contentType est défini sur "application/json". Une fois que j'ai supprimé cette ligne, tout fonctionnait très bien.

var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },

               { "position": "235.1944023323615", "markerPosition": "19" },

               { "position": "42.5978231292517", "markerPosition": "-3" }];

$.ajax({

    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify({ Markers: markers }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){alert(data);},
    failure: function(errMsg) {
        alert(errMsg);
    }
});
Usha
la source
2

J'ai rencontré celui-ci aussi et c'est ma solution.

Si vous rencontrez une exception d'objet json non valide lors de l'analyse des données, même si vous savez que votre chaîne json est correcte, chaînez les données que vous avez reçues dans votre code ajax avant de les analyser en JSON:

$.post(CONTEXT+"servlet/capture",{
        yesTransactionId : yesTransactionId, 
        productOfferId : productOfferId
        },
        function(data){
            try{
                var trimData = $.trim(JSON.stringify(data));
                var obj      = $.parseJSON(trimData);
                if(obj.success == 'true'){ 
                    //some codes ...
Clare Panganoron
la source
1

J'ai une requête,

$("#login-button").click(function(e){ alert("hiii");

        var username = $("#username-field").val();
        var password = $("#username-field").val();

        alert(username);
        alert("password" + password);



        var markers = { "userName" : "admin","password" : "admin123"};
        $.ajax({
            type: "POST",
            url: url,
            // The key needs to match your method's input parameter (case-sensitive).
            data: JSON.stringify(markers),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(data){alert("got the data"+data);},
            failure: function(errMsg) {
                alert(errMsg);
            }
        });

    });

Je publie les informations de connexion dans json et j'obtiens une chaîne en tant que "Success", mais je n'obtiens pas de réponse.

Priya B
la source
1
Ce n'est pas la réponse à la question. Si vous souhaitez poser la question, allez dans le menu "Question" et cliquez sur "Poser une question", et si votre question est liée à cette question, fournissez le lien de référence dans votre question.
Mittal Patel
-2

Veuillez suivre ceci par un appel ajax au service Web de java var param = {feildName: feildValue}; JSON.stringify ({data: param})

$.ajax({
            dataType    : 'json',
            type        : 'POST',
            contentType : 'application/json',
            url         : '<%=request.getContextPath()%>/rest/priceGroups',
            data        : JSON.stringify({data : param}),
            success     : function(res) {
                if(res.success == true){
                    $('#alertMessage').html('Successfully price group created.').addClass('alert alert-success fade in');
                    $('#alertMessage').removeClass('alert-danger alert-info');
                    initPriceGroupsList();
                    priceGroupId = 0;
                    resetForm();                                                                    
                }else{                          
                    $('#alertMessage').html(res.message).addClass('alert alert-danger fade in');
                }
                $('#alertMessage').alert();         
                window.setTimeout(function() { 
                    $('#alertMessage').removeClass('in');
                    document.getElementById('message').style.display = 'none';
                }, 5000);
            }
        });
Ravi Panchal
la source
voici comment lister les objets passés en json à l'appel ajax de java webservice.
Ravi Panchal