Pregunta

Mi SOLICITUD HTTP contiene una cadena JSON válida que tiene la comilla doble en medio del nombre "jo\"hn" escapada como se ve aquí (capturada por Fiddler Web Debugger)

{"name":"firstName","value":"jo\"hn"},

Nota:El proceso de envío de solicitudes utiliza el jQuery estándar. $.ajax(..) llamar como se ve en este artículo sin problema.


Problema del lado del servidor

Mi método de servicio web C# ASMX recibe el siguiente valor de cadena de C# que tiene la comilla doble del medio sin escape (es decir,se ha eliminado la barra invertida).Esto no se puede deserializar sin causar el error que se ve a continuación.

Aquí es donde ocurre la disjunción en el proceso, antes de recibir el valor en mi método web.Es como si ASP.NET estuviera procesando la cadena internamente quitándole el escape y volviéndola a armar sin escapes, alterando el valor original en lugar de proporcionarlo palabra por palabra al parámetro del método web.

La cadena C# es:

{"name":"firstName","value":"jo"hn"},

El método web ASMX es aproximadamente:

using System.Web.Script.Serialization;
using System.Web.Script.Services;

[WebMethod]
[ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public string saveData(string values)
{
    JavaScriptSerializer json = new JavaScriptSerializer();
    request = json.Deserialize<List<NameValuePair>>(values.ToString());
                // ^^^ KABOOM! 

Es comprensible que el mensaje de excepción sea:

{"Se pasó un objeto no válido, se esperaba ':' o '}'. (423):[{\"nombre\":\"plc$lt$zoneHeaderTopNav$searchBoxTopNav$txtWord\",\"valor\":\"\"},{\"nombre\":\"saludo\",\"valor \":\"Señor\"},{\"nombre\":\"nombre\",\"valor\":\"joh\"n\"},{\"nombre\":\"apellido\ ",\"valor\":\"smith\"},{\"nombre\":\"inicial\",\"valor\":\"d\"}]"}

¿Cuál es la mejor manera de resolver este problema sin alejarme de los servicios web ASMX clásicos?

Podría considerar un controlador frontal que limpie la solicitud entrante, o tal vez ejecutar una limpieza de cadenas al comienzo del método del servicio web.Quizás una biblioteca JSON diferente.

Sin embargo, me pregunto si hay una respuesta fácil:¿Modificar la configuración, utilizar un atributo, una configuración o un método de sobrecarga que pueda resolver el problema?

He investigado bastante en Internet, pero la mayoría de los artículos cubren la devolución de datos JSON del servidor al cliente y cómo abordar problemas en esa área.


Nota complementaria:detalles completos de la llamada del lado del cliente solicitados por Darin Dimitrov

ACTUALIZAR:La respuesta de Darin publicada aquí en línea, para facilitar la referencia

function SaveDraft() {

    $.checklist.checkvalid();
    var formObj = $(':input:not([type=hidden])').serializeArray();

    var request = JSON.stringify(formObj);
    request = request.replace(/'/g, "");

    $.ajax({
        url: "/Service.asmx/saveData",
        type: "POST",

        // *** Original erroneous line: uses string concat - commented out
        // data: "{'values':'" + request + "'}",

        // *** CORRECTED LINE: provides an object instead of a string and calls JSON stringify.
        data: JSON.stringify({ values: request }), 

        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: SaveDraftSuccess,
        error: SaveDraftFail
    });
}

Nota:Esta es la encarnación de la llamada que produce el fragmento JSON válido que se muestra en la parte superior de la pregunta.

¿Fue útil?

Solución

¿Por qué estás haciendo esta horrible deserialización JSON manual en tu servicio web?Déjame sugerirte un enfoque mucho mejor.

Comience por definir un modelo:

public class Person
{
    public string Name { get; set; }
    public string Value { get; set; }
}

luego un método web:

[WebMethod]
[ScriptMethod]
public string SaveData(Person person)
{
    ...
}

y luego podrías invocarlo desde javascript.Por ejemplo usando jQuery:

$.ajax({
    url: 'foo.asmx/SaveData',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({
        person: {
            name: 'firstName',
            value: ' jo\"h\'n'
        }
    }),
    success: function(result) {
        alert(result.d);
    }
});

Ya no hay kabooms.

El JSON.stringify El método que se muestra aquí está integrado en los navegadores modernos, pero si necesita admitir navegadores heredados, puede incluir el json2.js script a su página.


ACTUALIZAR:

Ahora que ha mostrado su código, parece que no está codificando su solicitud.Prueba así:

var formObj = $(':input:not([type=hidden])').serializeArray();
var request = JSON.stringify(formObj);
$.ajax({
    url: "/Service.asmx/saveData",
    type: "POST",
    data: JSON.stringify({ values: request }),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: SaveDraftSuccess,
    error: SaveDraftFail
});

Cosas a tener en cuenta:no necesita expresiones regulares para eliminar comillas simples y debe usar JSON.stringify para codificar correctamente los valores de su solicitud.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top