简体   繁体   中英

jQuery and WCF WebService Deserialization issues

I had a WebService in an ASMX file, however i ended up having issues with it since, under some circumstances i had too much data (Printing a paged Grid, retrieves all data). Found out that i can't configure much of anything related to message size with ASMX services, so i decided to go the WCF route to solve my issue.

Converting my existing WebService, i created an interface and the actual service and then added my configurations to my WebConfig. So far so good. After converting, i can't manage to get it to run. I have a breakpoint on the first line of my Method and it never reaches it.

Chrome gives me "400 (Bad Format)" errors on the call, so i went and configured Tracing. In the traces, i see an exception being raised on the call of my method.

There was an error while trying to deserialize parameter http://tempuri.org/:jsonAOData. Please see InnerException for more details.

(Full exception, sorry in French)

Le serveur a rencontré une erreur lors du traitement de la demande. Le message d'exception est 'Le module de formatage a généré une exception en tentant de désérialiser le message : Une erreur s'est produite en tentant de désérialiser le paramètre http://tempuri.org/:jsonAOData. Le message InnerException était 'Une erreur s'est produite lors de la désérialisation de l'objet de type System.String. Jeton 'null' attendu, mais 'name' a été trouvé.'. Pour plus d'informations, consultez InnerException.'. Pour plus d'informations, consultez les journaux du serveur. La trace de la pile d'exception est :

à System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part) 
à System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeParameter(XmlDictionaryReader reader, PartInfo part) 
à System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, PartInfo returnInfo, Object& returnValue) 
à System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object[] parameters, Boolean isRequest) 
à System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest) 
à System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest) 
à System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters) 
à System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters) 
à System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters) 
à System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters) à System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) 
à System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Looking at the call in chrome, it specifies the following:

Request URL:http://localhost:2806/MyWebApp/WebServices.svc/GetRequests
Request Method:POST
Status Code:400 Bad Request
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,fr-CA;q=0.6,fr;q=0.4
Connection:keep-alive
Content-Length:3436
Content-Type:application/json; charset=UTF-8
Cookie:DOKU_PREFS=list%23thumbs; ASP.NET_SessionId=bttjyzhltsrxflcn43i0v43f; MyWebApp=ECFF341038FFA20B7357CAEE592127F98B46F7421F5388A6CCB1D8460A1A66E345D82E62F634BF2854F9008DD01C875B53B3864E3EE3511AFAC67C40AE9BB4013E367D50605B326755CA7F286EF18CD7A3E229EDA2EE8066A12DC330B293AEE549322C7AADC46306CA63402A27F6F125703D070B07EE8BBDA9AC2F185CF546DDEAF1AA6AEE6B42BAFF41BDDC690CDED8
Host:localhost:2806
Origin:http://localhost:2806
Referer:http://localhost:2806/MyWebApp/Viewer.aspx
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11
X-Requested-With:XMLHttpRequest

Payload (that i validated using JSONLint):

{"jsonAOData": "[{"name":"sEcho","value":1},{"name":"iColumns","value":33},{"name":"sColumns","value":"FileId,StateDesc,DeptDescription,Division,ConfirmProblem,TaskDescription,GenComment,FileType,Problem,TreatmentTargetDate,TreatmentPlannedDate,Responsable,ReceivedDate,NoCiv,Generic,Streetname,StreetDirection,StreetDescription,TreatmentStartDate,TreatmentCompleteDate,TreatmentDemandDate,SiteDesc,SectorOld,District,AreaOld,IntersectStreetId,Prepose,PrintedDate,Requester,AdressC,LocationPrecision,RealisedFor,Source"},{"name":"iDisplayStart","value":0},{"name":"iDisplayLength","value":-1},{"name":"mDataProp_0","value":"FileId"},{"name":"mDataProp_1","value":"StateDesc"},{"name":"mDataProp_2","value":"DeptDescription"},{"name":"mDataProp_3","value":"Division"},{"name":"mDataProp_4","value":"ConfirmProblem"},{"name":"mDataProp_5","value":"TaskDescription"},{"name":"mDataProp_6","value":"GenComment"},{"name":"mDataProp_7","value":"FileType"},{"name":"mDataProp_8","value":"Problem"},{"name":"mDataProp_9","value":"TreatmentTargetDate"},{"name":"mDataProp_10","value":"TreatmentPlannedDate"},{"name":"mDataProp_11","value":"Responsable"},{"name":"mDataProp_12","value":"ReceivedDate"},{"name":"mDataProp_13","value":"NoCiv"},{"name":"mDataProp_14","value":"Generic"},{"name":"mDataProp_15","value":"Streetname"},{"name":"mDataProp_16","value":"StreetDirection"},{"name":"mDataProp_17","value":"StreetDescription"},{"name":"mDataProp_18","value":"TreatmentStartDate"},{"name":"mDataProp_19","value":"TreatmentCompleteDate"},{"name":"mDataProp_20","value":"TreatmentDemandDate"},{"name":"mDataProp_21","value":"SiteDesc"},{"name":"mDataProp_22","value":"SectorOld"},{"name":"mDataProp_23","value":"District"},{"name":"mDataProp_24","value":"AreaOld"},{"name":"mDataProp_25","value":"IntersectStreetId"},{"name":"mDataProp_26","value":"Prepose"},{"name":"mDataProp_27","value":"PrintedDate"},{"name":"mDataProp_28","value":"Requester"},{"name":"mDataProp_29","value":"AdressC"},{"name":"mDataProp_30","value":"LocationPrecision"},{"name":"mDataProp_31","value":"RealisedFor"},{"name":"mDataProp_32","value":"Source"},{"name":"iSortCol_0","value":0},{"name":"sSortDir_0","value":"asc"},{"name":"iSortingCols","value":1},{"name":"bSortable_0","value":true},{"name":"bSortable_1","value":true},{"name":"bSortable_2","value":true},{"name":"bSortable_3","value":true},{"name":"bSortable_4","value":true},{"name":"bSortable_5","value":true},{"name":"bSortable_6","value":true},{"name":"bSortable_7","value":true},{"name":"bSortable_8","value":true},{"name":"bSortable_9","value":true},{"name":"bSortable_10","value":true},{"name":"bSortable_11","value":true},{"name":"bSortable_12","value":true},{"name":"bSortable_13","value":true},{"name":"bSortable_14","value":true},{"name":"bSortable_15","value":true},{"name":"bSortable_16","value":true},{"name":"bSortable_17","value":true},{"name":"bSortable_18","value":true},{"name":"bSortable_19","value":true},{"name":"bSortable_20","value":true},{"name":"bSortable_21","value":true},{"name":"bSortable_22","value":true},{"name":"bSortable_23","value":true},{"name":"bSortable_24","value":true},{"name":"bSortable_25","value":true},{"name":"bSortable_26","value":true},{"name":"bSortable_27","value":true},{"name":"bSortable_28","value":true},{"name":"bSortable_29","value":true},{"name":"bSortable_30","value":true},{"name":"bSortable_31","value":true},{"name":"bSortable_32","value":true}]"}

For references, im also including some configurations / code snippets to help troubleshoot it :

my (partial) jQuery (DataTables) initialisation

sAjaxSource: "WebServices.svc/GetRequests",
fnServerData: function (sSource, aoData, fnCallback) {
    var jsonAOData = JSON.stringify(aoData);
    $.ajax({
        type: "POST",
        dataType: 'json',
        contentType: "application/json; charset=utf-8",
        url: sSource,
        data: '{"jsonAOData": "' + jsonAOData + '"}',
        success: function (msg) {
            fnCallback(msg.d);
            }
        });
    }

My method definition in IWebServices:

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
FormatedList GetRequests(string jsonAOData);

It's implementation (There is no attributes/decorations around it), in WebServices.cs, which WebServices.svc inherits of.

public FormatedList GetRequests(string jsonAOData)
{
    // My code that was working before but never gets call now.
}

My WebConfig

<system.serviceModel>
   <behaviors>
      <serviceBehaviors>
         <behavior name="WebServicesBehavior">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
         </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
         <behavior name="WebServicesAspNetAjaxBehavior">
            <webHttp/>
         </behavior>
      </endpointBehaviors>
   </behaviors>
   <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
   <services>
      <service behaviorConfiguration="WebServicesBehavior" name="WebServices">
         <endpoint address="" behaviorConfiguration="WebServicesAspNetAjaxBehavior"
            binding="webHttpBinding" contract="IWebServices" />
      </service>
   </services>
</system.serviceModel>

Any idea what is it that im missing ? I'm sure im fairly close to my goal, just can't grasp the last little bit...

Thanks!

The problem is that your JSON data is invalid.

{"jsonAOData": "[{"name":"sEcho"...

A JSON string starts with the " character and ends at a matching " character (unless it's escaped as \\" ). Your string starts at [{ and ends there. The characters after that are invalid ( name ).

If you want the string to be passed as is, you'll actually need to "re-JSONify" it. First, you'll create a JSON string which you want to pass to the service ( jsonAOData ). Then you'll create a new object which will be passed to the WCF service (and that object needs to be JSONified as well) - see below.

var jsonAOData = JSON.stringify(aoData);
var inputBody = JSON.stringify({ jsonAOData: jsonAOData });
$.ajax({
    type: "POST",
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    url: sSource,
    data: inputBody,
    success: function (msg) {
        fnCallback(msg.d);
        }
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM