我的Silverlight 4应用程序通过WCF服务从服务器下载了相当多的数据,因此我使用此处描述的技术实现了gzip压缩:http://forums.infragistics.com/blogs/anton_staykov/archive/2010/08/24/silverlight-wcf-service-compression-azure.aspx
简而言之,我扩展了WCF gzip编码器示例(http://msdn.microsoft.com/en-us/library/ms751458.aspx)以使用Silverlight。服务器使用gzip压缩WCF响应,在客户端,浏览器HTTP堆栈在响应Silverlight之前自动解压缩响应。一切都很好,压缩在IE中运行得非常好。
然而,在Chrome中测试同样的事情会导致这个......
System.Xml.XmlException: The input source is not correctly formatted.
at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
at System.Xml.XmlBufferReader.ReadValue(XmlBinaryNodeType nodeType, ValueHandle value)
at System.Xml.XmlBinaryReader.ReadNode()
at System.Xml.XmlBinaryReader.Read()
at System.Xml.XmlBaseReader.ReadEndElement()
at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion)
at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataServiceClient.RealTimeDataServiceClientChannel.EndGetNowTime(IAsyncResult result)
at DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataServiceClient.DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataService.EndGetNowTime(IAsyncResult result)
at DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataServiceClient.OnEndGetNowTime(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)
我已经检查了Fiddler中两个浏览器的请求+响应,它们几乎完全相同,但有一个重要的区别 - 响应的内容长度设置错误,Chrome 。我确信这就是XML SOAP无法解析的原因。由于内容长度不正确,Chrome只会解压缩部分内容。是什么赋予了?为什么我的WCF服务会为Chrome发送错误的内容长度而不是IE?我只改变浏览器 - 代码是相同的,响应主体是相同的(Fiddler可以解压缩都很好)。任何人都知道为什么会发生这种情况?
的Fiddler:
~~ Internet Explorer 9 ~~
请求
POST http://127.0.0.1:84/services/RealTimeDataService.svc/binary HTTP/1.1
Accept: */*
Referer: http://127.0.0.1:84/ClientBin/Silverlight4.View.xap
Accept-Language: en-US
Content-Length: 207
Content-Type: application/soap+msbin1
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: 127.0.0.1:84
Connection: Keep-Alive
Pragma: no-cache
响应
HTTP/1.1 200 OK
Cache-Control: private,no-cache
Pragma: no-cache
Content-Length: 512
Content-Type: application/soap+msbin1
Content-Encoding: gzip
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 08 Jul 2011 16:18:09 GMT
~~ Chrome ~~
请求
POST http://127.0.0.1:84/services/RealTimeDataService.svc/binary HTTP/1.1
Host: 127.0.0.1:84
Connection: keep-alive
Referer: http://127.0.0.1:84/ClientBin/Silverlight4.View.xap
Content-Length: 207
Origin: http://127.0.0.1:84
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30
content-type: application/soap+msbin1
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
响应
HTTP/1.1 200 OK
Cache-Control: private,no-cache
Pragma: no-cache
Content-Length: 149
Content-Type: application/soap+msbin1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 08 Jul 2011 16:05:43 GMT
Content-Encoding: gzip
答案 0 :(得分:0)
我最终实现了一种解决方法来压缩WCF服务响应并在Silverlight库上解压缩它。我使用了SharpZipLib:
在我的WCF服务中,我有压缩和未压缩的方法..压缩方法返回byte [],在Silverlight端解码。我公开了未压缩的方法,它返回原始对象,因为我需要将这些对象的类暴露给客户端。 (如果有人对如何做到这一点有更好的了解,我很乐意听到它)
让不为这些响应设置内容编码HTTP标头,因为它们由SL客户端应用程序处理,而不是由浏览器处理。
我无法弄清楚为什么Chrome不会自动解压缩我的WCF响应,但这种解决方法可以达到相同的效果。