Jquery Ajax Publicar json en el servicio web

238

Estoy tratando de publicar un objeto JSON en un servicio web asp.net.

Mi json se ve así:

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

Estoy usando json2.js para stringyfy mi objeto json.

y estoy usando jquery para publicarlo en mi servicio web.

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

Estoy teniendo el siguiente error:

"Primitiva JSON no válida:

He encontrado un montón de publicaciones relacionadas con esto y parece ser un problema muy común, pero nada de lo que intento soluciona el problema.

Cuando firebug lo que se publica en el servidor se ve así:

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

Mi función de servicio web que se llama es:

[WebMethod]
public string CreateMarkers(string markerArray)
{
    return "received markers";
}
Código Faraón
fuente
'fracaso' no se proporciona como una posible configuración entre los que figuran en api.jquery.com/jQuery.ajax ... ¿tal vez lo confundiste con 'error'?
danicotra

Respuestas:

390

Usted mencionó el uso de json2.js para stringificar sus datos, pero los datos PUBLICADOS parecen ser JSON URLEncoded Puede que ya lo haya visto, pero esta publicación sobre la primitiva JSON inválida cubre por qué JSON está siendo URLEncoded.

Yo aconsejaría contra el paso de una cadena de texto, serializado manualmente-JSON en el método . ASP.NET va a deserializar automáticamente JSON los datos POST de la solicitud, por lo que si está serializando y enviando manualmente una cadena JSON a ASP.NET, en realidad terminará teniendo que JSON serializar su cadena serializada JSON.

Sugeriría algo más en este sentido:

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 clave para evitar el problema primitivo JSON no válido es pasar jQuery una cadena JSON para el dataparámetro, no un objeto JavaScript, para que jQuery no intente URLEncode sus datos.

En el lado del servidor, combine los parámetros de entrada de su método con la forma de los datos que está pasando:

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.";
}

También puede aceptar una matriz, como Marker[] Markers, si lo prefiere. El deserializador que utiliza ASMX ScriptServices (JavaScriptSerializer) es bastante flexible y hará todo lo posible para convertir sus datos de entrada en el tipo de servidor que especifique.

Dave Ward
fuente
44
Usted escribió "para que jQuery no intente URLEncode sus datos", pero no es correcto. Para evitar que jquery codifique sus datos, debe establecer processData en falso.
Softlion
8
Pasar una cadena es suficiente para evitar que jQuery URLEncoding el parámetro de datos. Puede establecer processData en falso, pero es superfluo (y hacerlo solo, sin pasar una cadena JSON para los datos, no es suficiente).
Dave Ward el
1
Este mismo problema (y respuesta) también se aplica a Rails.
GregT
2
@DaveWard ¿ contentTypeSe considera si usamos GET y no POST?
Royi Namir
@RoyiNamir Si está utilizando ASMX ScriptServices o ASPX WebMethods, debe usar POST para que devuelvan JSON. Si obtiene, Content-Type correcto o no, obtendrá XML en su lugar.
Dave Ward
19
  1. markersNo es un objeto JSON. Es un objeto JavaScript normal.
  2. Lea sobre la data:opción :

    Datos a enviar al servidor. Se convierte en una cadena de consulta , si aún no es una cadena.

Si desea enviar los datos como JSON, primero debe codificarlos:

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

jQuery no convierte objetos o matrices a JSON automáticamente.


Pero supongo que el mensaje de error proviene de interpretar la respuesta del servicio. El texto que envía no es JSON. Las cadenas JSON deben estar entre comillas dobles. Entonces tendrías que hacer:

return "\"received markers\"";

No estoy seguro de si su problema real es enviar o recibir datos.

Felix Kling
fuente
Gracias por ayudar a Felix, pensé que al ejecutar marcadores a través del método JSON.stringyfy lo estaba convirtiendo en una cadena de consulta, hice lo que sugirió, pero desafortunadamente no funciona. No estoy publicando lo siguiente.
Código Faraón
marcadores =% 7B% 22 marcadores% 22% 3A% 5B% 7B% 22 posición% 22% 3A% 22128.3657142857143% 22% 2C% 22markerPosition% 22% 3A% 227% 22% 7D% 2C% 7B% 22position% 22% 3A% 22235.1944023323615 % 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
Código Faraón
@Dreamguts: No me queda claro qué quieres. ¿Quieres enviar markerscomo cadena JSON?
Felix Kling
Hola Felix, sí, quiero enviar el objeto de marcadores como una cadena JSON para poder usarlo en mi servicio web.
Código Faraón
@Dreamguts: Entonces debería funcionar de esta manera. También el "código" que publicaste en el comentario se ve bien. Por supuesto, debe decodificarlo correctamente en el lado del servidor y tal vez deba cambiar el nombre del parámetro, no lo sé.
Felix Kling
3

Intenté la solución de Dave Ward. La parte de datos no se enviaba desde el navegador en la parte de carga útil de la solicitud de publicación como contentType está configurado en "application/json". Una vez que eliminé esta línea, todo funcionó muy 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
fuente
2

También me he encontrado con este y esta es mi solución.

Si encuentra una excepción de objeto json no válida al analizar datos, aunque sepa que su cadena json es correcta, haga una cadena de los datos que recibió en su código ajax antes de analizarlos 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
fuente
1

Tengo consulta,

$("#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);
            }
        });

    });

Estoy publicando los detalles de inicio de sesión en json y obtengo una cadena como "Success", pero no obtengo la respuesta.

Priya B
fuente
1
Esta no es la respuesta a la pregunta. Si desea hacer la pregunta, vaya al menú "Pregunta" y haga clic en "Hacer pregunta", y si su pregunta está relacionada con esta pregunta, proporcione el enlace de referencia en su pregunta.
Mittal Patel el
-2

Siga esto mediante una llamada ajax al servicio 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
fuente
aquí cómo enumerar el objeto pasar a json a la llamada ajax del servicio web java.
Ravi Panchal