将数据从 jquery ajax 请求传递到 wcf 服务失败反序列化?

Posted

技术标签:

【中文标题】将数据从 jquery ajax 请求传递到 wcf 服务失败反序列化?【英文标题】:Passing data from a jquery ajax request to a wcf service fails deserialization? 【发布时间】:2010-10-10 00:36:00 【问题描述】:

我使用以下代码调用 wcf 服务。如果我调用一个不带参数但返回一个字符串的(测试)方法,它工作正常。如果我在我的方法中添加一个参数,我会得到一个奇怪的错误:

"ExceptionDetail":"HelpLink":null,"InnerException":null,"Message":"令牌 '\"' 是预期的,但在系统中找到了 '''。","StackTrace":" Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader 阅读器,字符串 res,String arg1,String arg2,String arg3)\u000d\u000a 在 System.Xml.XmlExceptionHelper.ThrowTokenExpected(XmlDictionaryReader 阅读器,预期字符串,找到字符)\u000d\u000a 在系统。 Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a 在 System.Runtime.Serialization.Json.XmlJsonReader.Read()\u000d\u000a 在 System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBodyCore(XmlDictionaryReader reader, Object[]参数,布尔 isRequest)\u000d\u000a 在 System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader 阅读器,MessageVersion 版本,字符串操作,MessageDescription messageDescription,Object[] 参数,布尔 isRequest)\u000d\u000a 在 System.ServiceMode l.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 在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)\u000d\u000a 在 System.ServiceModel.Dispatcher.Immut ableDispatchRuntime.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 at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)","Type":"System.Xml.XmlException","ExceptionType":"System .Xml.XmlException","Message":"令牌 '\"' 是预期的,但找到了 '''。","StackTrace":" 在 System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1,字符串 arg2,字符串 arg3)\u000d\u000a 在 System.Xml.XmlExceptionHelper.ThrowTokenExpected(XmlDictionaryReader 阅读器,预期字符串,找到字符)\u000d\u000a 在 System.Runtime.Serialization.Json.XmlJsonReader.ParseStartElement()\u000d\u000a在 System.Runtime.Serialization.Json.XmlJsonRe ader.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版本,字符串操作,MessageDescription messageDescription,Object[] 参数,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[] 参数)\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 在 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)"

我的 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";
    

它被放置在一个具有以下属性的类中:

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

我不会在 web.config 中列出配置以保持这条长消息“简短”,但如果有人认为他们可以使用它,我可以发布它 - 我只是想强调我可以调用一个方法并获得一个结果 - 只要我不将任何数据传递给 wcf 服务,我就可以读取字符串甚至 json 对象。

【问题讨论】:

【参考方案1】:

在您发送到服务的 JSON 中使用双引号而不是单引号。也就是改变:

data: "'customerId': '2'",

data: '"customerId": "2"',

我已经在本地对此进行了测试,这解决了问题。

顺便说一句,我使用一种在使用内置 ASP.NET 工具以外的库调用 ASMX 和 WCF 服务时经常使用的方法来调试它。我使用由asp:ScriptReference 创建的客户端代理调用服务,然后使用HTTP 嗅探器检查发送到服务器的请求(例如用于FireFox 的HttpFox)并将请求与jQuery 发送的请求进行比较.然后您通常可以快速查看请求的不同之处(因此可能是错误的)。在这种情况下,很明显发送的 POST 数据存在差异。

【讨论】:

这太疯狂了——实际上我在阅读您的帖子之前就这样做了,但它没有用。然后我想,如果我删除了发布(并且我添加)的 WebInvoke 属性 davogones,它可能会起作用并且确实有效! 经过一番反思(关于我的错误),我意识到我只是在序列化 json 方面很糟糕:P 我的数据没有正确格式化 json - 这不是魔法,json 需要双引号而不是单引号。 javascript 可能不关心,但 json 关心,所以它当然应该是这样的。 谢谢丹尼尔........PHEW。当您说 JavaScript 可能不关心,但 JSON 关心时,这绝对是正确的。谢谢。【参考方案2】:

我只认为发布对于用户名和密码登录功能是必不可少的,所以这就是我对发送到 Web 服务的 JSon 参数进行编码的方式...

这是网络服务合同..

    [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 服务的问题...按照代码...

函数格式JsonDataToWCFPost(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 calls to a WCF REST Service 了解更多信息。

【讨论】:

我添加了属性,但我仍然得到一个错误 - 不幸的是我现在得到的错误是空的,所以我看不到新问题是什么。我什至尝试添加“RequestFormat = WebMessageFormat.Json”

以上是关于将数据从 jquery ajax 请求传递到 wcf 服务失败反序列化?的主要内容,如果未能解决你的问题,请参考以下文章

将数据传递到处理程序的 Jquery ajax 不起作用(Asp.net、C#、Jquery)

使用jquery将数据从视图传递到控制器

使用 jQuery 的 $.ajax() 将多个 Json 对象作为数据传递

如何将 JQuery AJAX 请求中的字符串值传递给 Spring Boot 控制器?

从 JQUERY 传递数据 | AJAX 处理 ASP.NET

将数据数组从表单传递到 ajax 到 PHP 发布文件