Jquery Ajax Δημοσίευση json σε webservice

Προσπαθώ να στείλω ένα αντικείμενο JSON σε μια webservice asp.net.

Το json μου μοιάζει με αυτό:

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

Χρησιμοποιώ το json2.js για να κάνω stringyfy το json αντικείμενό μου.

και χρησιμοποιώ το jquery για να το στείλω στο 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);
        }
  });

Λαμβάνω το ακόλουθο σφάλμα:

"Invalid JSON primitive:

Έχω βρει ένα σωρό δημοσιεύσεις που σχετίζονται με αυτό και φαίνεται να είναι ένα πραγματικά κοινό πρόβλημα, αλλά τίποτα δεν δοκιμάζω διορθώνει το πρόβλημα.

Όταν το firebug τι δημοσιεύεται στον διακομιστή φαίνεται ως εξής:

markers%5B0%5D%5Bposition%5D=128.3657142857143&markers%5B0%5D%5BmarkerPosition%5D=7&markers%5B1%5D%5Bposition%5D=235.1944023323615&markers%5B1%5D%5BmarkerPosition%5D=19&markers%5B2%5D%5Bposition%5D=42.5978231292517&markers%5B2%5D%5BmarkerPosition%5D=-3

Η συνάρτηση webservice που καλείται είναι η εξής:

[WebMethod]
public string CreateMarkers(string markerArray)
{
    return "received markers";
}
Λύση

Αναφέρατε τη χρήση του json2.js για τη μετατροπή των δεδομένων σας σε συμβολοσειρές, αλλά τα δεδομένα που αποστέλλονται με POST φαίνεται να είναι JSON με κωδικοποίηση URLEncoded Μπορεί να το έχετε ήδη δει, αλλά αυτή η δημοσίευση σχετικά με το άκυρο JSON primitive καλύπτει τον λόγο για τον οποίο το JSON είναι κωδικοποιημένο με URLEncoded.

Θα συμβούλευα να μην περνάτε ένα ακατέργαστο, χειροκίνητα σειριοποιημένο JSON string στη μέθοδό σας. Το ASP.NET πρόκειται να κάνει αυτόματα JSON deserialize τα δεδομένα POST του αιτήματος, οπότε αν κάνετε χειροκίνητη σειριοποίηση και στέλνετε μια συμβολοσειρά JSON στο ASP.NET, στην πραγματικότητα θα καταλήξετε να πρέπει να σειριοποιήσετε την σειριοποιημένη συμβολοσειρά JSON σας.

Θα πρότεινα κάτι περισσότερο κατά μήκος αυτών των γραμμών:

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);
    }
});

Το κλειδί για την αποφυγή του προβλήματος του άκυρου JSON primitive είναι να περάσετε στην jQuery ένα JSON string για την παράμετρο data, όχι ένα αντικείμενο JavaScript, έτσι ώστε η jQuery να μην προσπαθήσει να URLEncode τα δεδομένα σας.

Στην πλευρά του διακομιστή, αντιστοιχίστε τις παραμέτρους εισόδου της μεθόδου σας με το σχήμα των δεδομένων που περνάτε:

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

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

Μπορείτε επίσης να δεχτείτε έναν πίνακα, όπως Marker[] Markers, αν προτιμάτε. Ο deserializer που χρησιμοποιεί το ASMX ScriptServices (JavaScriptSerializer) είναι αρκετά ευέλικτος, και θα κάνει ό,τι μπορεί για να μετατρέψει τα δεδομένα εισόδου σας στον τύπο server-side που καθορίζετε.

Σχόλια (13)
  1. Το markers δεν είναι αντικείμενο JSON. Είναι ένα κανονικό αντικείμενο JavaScript.
  2. Διαβάστε για την επιλογή data::

    Δεδομένα που πρέπει να αποσταλούν στον διακομιστή. Μετατρέπονται σε ένα query string, αν δεν είναι ήδη string.

Αν θέλετε να στείλετε τα δεδομένα ως JSON, πρέπει πρώτα να τα κωδικοποιήσετε:

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

Το jQuery δεν μετατρέπει αυτόματα αντικείμενα ή πίνακες σε JSON.


Αλλά υποθέτω ότι το μήνυμα σφάλματος προέρχεται από την ερμηνεία της απόκρισης της υπηρεσίας. Το κείμενο που στέλνετε πίσω δεν είναι JSON. Οι συμβολοσειρές JSON πρέπει να περικλείονται σε διπλά εισαγωγικά. Οπότε θα πρέπει να κάνετε:

return "\"received markers\"";

Δεν είμαι σίγουρος αν το πραγματικό σας πρόβλημα είναι η αποστολή ή η λήψη των δεδομένων.

Σχόλια (9)

Έχω αντιμετωπίσει και εγώ αυτό το πρόβλημα και αυτή είναι η λύση μου.

Εάν αντιμετωπίζετε μια εξαίρεση άκυρου αντικειμένου json κατά την ανάλυση δεδομένων, παρόλο που γνωρίζετε ότι η συμβολοσειρά json είναι σωστή, αλφαριθμητικοποιήστε τα δεδομένα που λάβατε στον κώδικα ajax πριν τα αναλύσετε σε 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 ...
Σχόλια (0)