WCF 响应太长 - 身份验证错误
在我当前工作的项目中,公开了一个 WCF 服务,它返回一个业务实体数组,我们称之为发票:
Invoice[] GetInvoicesByTypeAndTime(InvoiceType invoiceType, byte startHour, byte? endHour);
使用的身份验证机制是 Windows 身份验证,WCF 服务托管在 IIS 6 上托管的 Web 应用程序中 起初,
当我获取超过 64kB 的数据时,会引发 CommunicationException,指出“已超出传入消息的最大消息大小配额 (65536)。要增加配额,请在相应的绑定元素上使用 MaxReceivedMessageSize 属性。”
好吧,我只是在 App.config 中将 maxReceivedMessageSize 和 maxBufferSize 的值增加到 65536000(我在末尾公然添加了三个零)(后者是因为它在 ArgumentException 中抱怨“对于 TransferMode.Buffered,MaxReceivedMessageSize 和 MaxBufferSize 必须是相同的值。 参数名称:绑定元素”)。
现在我可以收到更大的响应...
直到我达到另一个限制(我认为),在 624 个元素(大约 2.2 MB)之后,抛出一个奇怪的异常:
System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
服务器堆栈跟踪:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest request, HttpWebResponse response, WebException responseException, HttpChannelFactory factory)
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
异常重新抛出在 [ 0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Test2.DBS.IDbService.GetInvoicesByTypeAndTime(InvoiceType invoiceType, Byte startHour, Nullable`1 endHour)
at Test2.DBS.DbServiceClient.GetInvoicesByTypeAndTime(InvoiceType invoiceType, Byte startHour, Nullable`1 endHour) in D:\TEMP\Test2\Test2\Service References\DBS\Reference.cs:line 1445
at Test2.Program.Main(String[] args) in D:\TEMP\Test2\Test2\Program.cs:line 19
经过身份验证的响应是否有限制? ASP.NET 设置是否有限制?
In the project that I currently work for, there is exposed a WCF service which returns an array of a business entity, let's call it Invoice :
Invoice[] GetInvoicesByTypeAndTime(InvoiceType invoiceType, byte startHour, byte? endHour);
The authentication mechanism used is Windows Authentication, the WCF service is hosted in a Web Application hosted on IIS 6.
At first when I used to get data more than 64kB a CommunicationException was thrown stating that "The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element."
Fine, I just increased in App.config the values to 65536000 (I blatantly added three zeros at the end) for both maxReceivedMessageSize and maxBufferSize (the latter because it complained in an ArgumentException that "For TransferMode.Buffered, MaxReceivedMessageSize and MaxBufferSize must be the same value.
Parameter name: bindingElement").
Now I could receive larger responses...
Until I hit another limit (I THINK) in that after 624 elements (approx. 2.2 MB) a strange exception is thrown :
System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest request, HttpWebResponse response, WebException responseException, HttpChannelFactory factory)
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Test2.DBS.IDbService.GetInvoicesByTypeAndTime(InvoiceType invoiceType, Byte startHour, Nullable`1 endHour)
at Test2.DBS.DbServiceClient.GetInvoicesByTypeAndTime(InvoiceType invoiceType, Byte startHour, Nullable`1 endHour) in D:\TEMP\Test2\Test2\Service References\DBS\Reference.cs:line 1445
at Test2.Program.Main(String[] args) in D:\TEMP\Test2\Test2\Program.cs:line 19
Is there a limit on authenticated responses? Is there a limit from the ASP.NET settings?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜您正在使用 Windows 身份验证,因此会出现 401,而不是一条解释您如何超出消息限制的消息。当您通过 Windows 身份验证请求发送时,WCF 会发送 SOAP 请求两次,一次是失败并返回 Accept 标头,第二次是与 Windows 身份验证标头一起发送。
然而,根据我的测试,如果消息确实发送失败,您似乎仍然会收到 401。
为了解决这个问题,我必须输入服务器跟踪日志记录:
然后,我必须输入更大的读者配额,如上所述(但我使用了较小的值):
然后,您通常必须添加自定义行为以增加对象图中的最大项目数:
您需要将“behaviourConfiguration”属性添加到您的“
<” ;service>
”元素,其值为“MaximumItemsBehaviour”。我读过但不需要我自己的其他建议是添加:
并且:
I'm guessing that you're using Windows Authentication hence the 401 rather than a message explaining how you've blown your message limits. When you send through a Windows Authenticated request, WCF sends the SOAP request twice, once for it to fail and return an accepts header, and the second time to send it with the Windows Authentication headers.
However, from my testing, it looks like you still get the 401 if the message would have actually failed if it did get through.
To troubleshoot this, I had to put server trace logging in:
Then, I had to put in larger reader quotas, as above (but I used smaller values):
Then you generally have to put in a custom behaviour to increase the maximum number of items in an object graph:
You'll need to add a "behaviourConfiguration" attribute to your "
<system.serviceModel><services><service>
" element with the value "MaximumItemsBehaviour".Other advice I read, but didn't need myself was to add:
And:
如果您想要,请查看客户端的 readerQuotas TLDR 版本 - 要查看这是否确实是您的问题,您可以设置最大值 (Int32.MaxValue),如下所示。
Take a look at readerQuotas on the client side, if you want the TLDR version - to see if this is indeed your issue, you can set the max's (Int32.MaxValue) as shown below.