¿Pasar datos de una solicitud jquery ajax a un servicio wcf falla la deserialización?
json (4)
Creo que en su operación necesita este atributo:
[WebInvoke(Method="POST",
BodyStyle=WebMessageBodyStyle.Wrapped,
ResponseFormat=WebMessageFormat.Json
)]
Consulte las llamadas jQuery AJAX a un servicio WCF REST para obtener más información.
Uso el siguiente código para llamar a un servicio wcf. Si llamo a un método (de prueba) que no toma parámetros, pero devuelve una cadena, funciona bien. Si agrego un parámetro a mi método, obtengo un error extraño:
{"ExceptionDetail": {"HelpLink": null, "InnerException": null, "Mensaje": "Se esperaba el token ''/"'', pero se encontró '''' ''. "," StackTrace ":" en System.Xml.XmlExceptionHelper .ThrowXmlException (lector de XmlDictionaryReader, String res, String arg1, String arg2, String arg3) en System.Xml.XmlExceptionHelper.ThrowTokenExpected (lector de XmlDictionaryReader, String esperado, Char encontrado) en System.Runtime.Serialization .Json.XmlJsonReader.ParseStartElement () / u000d / u000a en System.Runtime.Serialization.Json.XmlJsonReader.Read () / u000d / u000a en System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore (lector de XmlDictionaryReader, Object [] parámetros, Boolean isRequest) / u000d / u000a en System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody (lector de XmlDictionaryReader, versión de MessageVersion, String action, MessageDescription messageDescription, Object [] parameters, Boolean isRequest) / u000d / u000a en System.ServiceModel.D ispatcher.OperationFormatter.DeserializeBodyContents (Message message, Object [] parameters, Boolean isRequest) / u000d / u000a en System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest (Message message, Object [] parameters) / u000d / u000a en System.ServiceModel.Dispatcher .DemultiplexingDispatchMessageFormatter.DeserializeRequest (Message message, Object [] parameters) / u000d / u000a en System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest (Message message, Object [] parameters) / u000d / u000a en System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest (Mensaje mensaje, Object [] parámetros) / u000d / u000a en System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.Immutabl eDispatchRuntime.ProcessMessage4 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2 (MessageRpc & rpc) / u000d / u000a en System. ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.MessageRpc.Process (Boolean isOperationContextSet) "," Type ":" System.Xml.XmlException "}," ExceptionType ":" System .Xml.XmlException "," Message ":" Se esperaba el token ''/ "'' pero se encontró '''' ''.", "StackTrace": "en System.Xml.XmlExceptionHelper.ThrowXmlException (lector de XmlDictionaryReader, String res, String arg1, String arg2, String arg3) en System.Xml.XmlExceptionHelper.ThrowTokenExpected (lector XmlDictionaryReader, String esperado, Char encontrado) en System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement () / u000d / u000a en System.Runtime.Serialization.Json.XmlJsonReade r.Read () / u000d / u000a en System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore (lector de XmlDictionaryReader, Object [] parámetros, Boolean isRequest) / u000d / u000a en System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody (XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object [] parameters, Boolean isRequest) / u000d / u000a en System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents (Message message, Object [] parameters, Boolean isRequest) / u000d / u000a en System.ServiceModel .Dispatcher.OperationFormatter.DeserializeRequest (Message message, Object [] parameters) / u000d / u000a en System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest (Message message, Object [] parameters) / u000d / u000a en System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter .DeserializeRequest (Mensaje mensaje, Object [] parámetros) / u000d / u000a en Sy stem.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest (Message message, Object [] parameters) / u000d / u000a en System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher .ImmutableDispatchRuntime.ProcessMessage3 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2 (MessageRpc & rpc) / u000d / u000a en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1 (MessageRpc & rpc) / u000d / u000a en System .ServiceModel.Dispatcher.MessageRpc.Process (Boolean isOperationContextSet) "}
Mi jquery se ve así, pero traté de cambiar los datos reales que envío como un json serie serializado (como se puede ver) a un objeto JSON puro con el mismo triste resultado.
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "ajax/Statistics.svc/Get7DaysStatistics",
dataType: "json",
data: "{''customerId'': ''2''}",
timeout: 10000,
success: function(obj) { updateStatistics(obj.d); },
error: function(xhr) {
if (xhr.responseText)
$("body").html(xhr.responseText);
else
alert(''unknown error'');
return;
}
});
El servicio wcf se ve así:
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic"), OperationContract]
public string Get7DaysStatistics(string customerId)
{
Debug.WriteLine(customerId);
return "Test done";
}
Se coloca en una clase con los siguientes atributos:
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
No voy a enumerar la configuración en el web.config para mantener este mensaje largo "corto", pero puedo publicarlo si alguien cree que pueden usarlo, solo quiero enfatizar que PUEDO llamar a un método y obtener un resultado - cadena o incluso un objeto json del que puedo leer, siempre y cuando NO pase datos al servicio wcf.
Hice una función en jscript que resolvió el problema para enviar datos vía POST a un servicio de WCF ... sigue el código ...
formato de funciónJsonDataToWCFPost (d) {
var t = {};
var a = ''{'';
for (var j = 0; j < d.length; j++) {
var x = d[j];
for (var i in x) {
if (x.hasOwnProperty(i)) {
var c = j + 1 == d.length ? ''}'' : '','';
a += (''"'' + i + ''":"'' + x[i] + ''"'' + c);
}
}
}
return a;
}
Solo he pensado que la publicación es esencial para la funcionalidad de inicio de sesión de usuario y contraseña, así que esta es la forma en que codifico los parámetros de JSon que envío al servicio web ...
Aquí está el contrato de servicio web.
[ServiceContract]
public interface ILogonService
{
[OperationContract]
[WebInvoke(
Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json
)]
string Logon(string un, string pw);
}
Aquí está el JQuery (¡Tenga en cuenta que el uso de "y" es importante!)
$.ajax({
type: ''POST'',
url: "/LogonService.svc/Logon",
data: ''{ "un": "'' + $(''#un'').val() + ''", "pw": "'' + $(''#pw'').val() + ''"}'',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
}
});
Use comillas dobles en lugar de comillas simples en el JSON que está enviando al servicio. Es decir, cambio:
data: "{''customerId'': ''2''}",
a
data: ''{"customerId": "2"}'',
He probado esto localmente y esto soluciona el problema.
Por cierto, depuré esto usando un método que solía usar cuando llamaba a servicios ASMX y WCF usando bibliotecas que no fueran las herramientas integradas de ASP.NET. Llamé al servicio usando el proxy del cliente creado por un asp:ScriptReference y luego inspeccioné la solicitud que se enviaba al servidor usando un sniffer HTTP (como HttpFox for FireFox) y HttpFox la solicitud con la que envía jQuery . Entonces, por lo general, puede ver rápidamente qué es diferente (y, probablemente, incorrecto) con la solicitud. En este caso, estaba claro que había una diferencia en los datos POST enviados.