Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data from a jquery ajax request to a wcf service fails deserialization?

Tags:

I use the following code to call a wcf service. If i call a (test) method that takes no parameters, but returns a string it works fine. If i add a parameter to my method i get a wierd error:

{"ExceptionDetail":{"HelpLink":null,"InnerException":null,"Message":"The token '\"' was expected but found '''.","StackTrace":" at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\u000d\u000a at System.Xml.XmlExceptionHelper.ThrowTokenExpected(XmlDictionaryReader reader, String expected, Char found)\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)","Type":"System.Xml.XmlException"},"ExceptionType":"System.Xml.XmlException","Message":"The token '\"' was expected but found '''.","StackTrace":" at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\u000d\u000a at System.Xml.XmlExceptionHelper.ThrowTokenExpected(XmlDictionaryReader reader, String expected, Char found)\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)\u000d\u000a at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)\u000d\u000a at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)"}

My jquery looks like this, but i tried changing the actual data which i send as a string serialized json (as you can see) to a pure json object with the same sad result.

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

The wcf service looks like this:

    [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic"), OperationContract]     public string Get7DaysStatistics(string customerId)     {         Debug.WriteLine(customerId);         return "Test done";     } 

It's placed in a a class with the following attributes:

[ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 

I won't list the configuration in the web.config to keep this long message "short" but i can post it if anybody thinks they can use it - i just want to stress that i CAN call a method and get a result - string or even a json object i can read from as long as i DON'T pass any data to the wcf service.

like image 244
Per Hornshøj-Schierbeck Avatar asked Feb 26 '09 07:02

Per Hornshøj-Schierbeck


1 Answers

Use double quotes instead of single quotes in the JSON you are sending to the service. That is, change:

data: "{'customerId': '2'}", 

to

data: '{"customerId": "2"}', 

I've tested this locally and this fixes the problem.

Incidentally, I debugged this using a method I've often used when calling ASMX and WCF services using libraries other than the built-in ASP.NET tools. I called the service using the client proxy created by an asp:ScriptReference and then inspected the request being sent to the server using an HTTP sniffer (such as HttpFox for FireFox) and compared the request to the one being sent by jQuery. Then you can usually quickly see what is different (and so probably wrong) with the request. In this case, it was clear that there was a difference in the POST data being sent.

like image 102
Daniel Richardson Avatar answered Oct 10 '22 18:10

Daniel Richardson