Подтвердить что ты не робот

Передача данных из jQuery ajax-запроса на службу wcf не позволяет выполнить десериализацию?

Я использую следующий код для вызова службы wcf. Если я вызываю метод (test), который не принимает никаких параметров, но возвращает строку, он отлично работает. Если я добавлю параметр в свой метод, я получаю wierd ошибку:

{ "ExceptionDetail": { "HelpLink": null, "InnerException": null, "Message": "Ожидается токен \", но найден '' '. "," StackTrace ":" at System. Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\u000d\u000a в System.Xml.XmlExceptionHelper.ThrowTokenExpected(читатель XmlDictionaryReader, String expected, Char found)\u000d\u000a at System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a в System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a в System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object [], Boolean isRequest)\u000d\u000a в System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, версия MessageVersion, действие String, MessageDescription messageDescription, Object [], Boolean isRequest)\u000d\u000a в System.ServiceMo del.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object [] parameters, Boolean isRequest)\u000d\u000a в System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a в System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a в System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a в System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a в System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) "," Тип ":" System.Xml.XmlException "}, ExceptionType ":" System.Xml.XmlException "," Message ":" Ожидается токен \", но найден '' '. "," StackTrace ":" в System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, Stri ng arg2, String arg3)\u000d\u000a в System.Xml.XmlExceptionHelper.ThrowTokenExpected(читатель XmlDictionaryReader, ожидаемая строка, Char найден)\u000d\u000a в System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a в System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a в System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object [] parameters, Boolean isRequest)\u000d\u000a в System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object [] parameters, Boolean isRequest)\u000d\u000a в System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object [] parameters, Boolean isRequest)\u000d\u000a в System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object [] parameters)\u0 00d\u000a в System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a в System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object [] parameters)\u000d\u000a в System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3 (MessageRpc & rpc)\u000d\u000a в системе .ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1 (MessageRpc & rpc)\u000d\u000a в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) "}

Мой jquery выглядит так, но я попытался изменить фактические данные, которые я отправляю как строку, сериализованную json (как вы можете видеть), на чистый json-объект с тем же грубым результатом.

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

Служба wcf выглядит следующим образом:

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

Он помещается в класс a со следующими атрибутами:

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

Я не буду перечислять конфигурацию в файле web.config, чтобы это длинное сообщение было "коротким", но я могу опубликовать его, если кто-то подумает, что он может его использовать - я просто хочу подчеркнуть, что я могу вызвать метод и получить result - строка или даже объект json, который я могу прочитать, пока я НЕ передаю данные в службу wcf.

4b9b3361

Ответ 1

Используйте двойные кавычки вместо одиночных кавычек в JSON, которые вы отправляете в службу. То есть, измените:

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

to

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

Я тестировал это локально, и это устраняет проблему.

Кстати, я отлаживал это, используя метод, который я часто использовал при вызове служб ASMX и WCF, используя библиотеки, отличные от встроенных инструментов ASP.NET. Я вызвал службу, используя прокси-сервер клиента, созданный asp: ScriptReference, а затем проверил запрос, отправляемый на сервер с помощью сниффера HTTP (например, HttpFox для FireFox) и сравнил запрос с тем, который был отправлен jQuery. Затем вы можете быстро увидеть, что отличается (и, вероятно, неправильно) с запросом. В этом случае было ясно, что разница в отправляемых данных POST.

Ответ 2

Я только думал, что публикация важна для функциональности имени пользователя и пароля, так что я могу кодировать параметры JSon, которые я отправляю в веб-службу...

Вот договор Webservice.

    [ServiceContract]
    public interface ILogonService
    {
    [OperationContract]
    [WebInvoke(
      Method = "POST",
      BodyStyle = WebMessageBodyStyle.WrappedRequest,
      ResponseFormat = WebMessageFormat.Json
    )]
    string Logon(string un, string pw);
    }

Вот JQuery (обратите внимание, что использование "и" важно!)

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

Ответ 3

Я сделал функцию в jscript, которая решила проблему для отправки данных через POST в службу WCF... следуйте коду...

function formatJsonDataToWCFPost (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;

}

Ответ 4

Я думаю, что для вашей операции вам нужен этот атрибут:

[WebInvoke(Method="POST",
           BodyStyle=WebMessageBodyStyle.Wrapped,
           ResponseFormat=WebMessageFormat.Json
)]

См. jQuery AJAX вызывает службу REST службы WCF для получения дополнительной информации.