在我目前工作的项目中,公开了一个WCF服务,它返回一个业务实体的数组,我们称之为Invoice:
Invoice[] GetInvoicesByTypeAndTime(InvoiceType invoiceType, byte startHour, byte? endHour);
使用的身份验证机制是Windows身份验证,WCF服务托管在IIS 6上托管的Web应用程序中。
首先,当我以前获取超过64kB的数据时,抛出了一个CommunicationException,指出“已超出传入邮件的最大邮件大小配额(65536)。要增加配额,请在相应的绑定元素上使用MaxReceivedMessageSize属性。“
很好,我刚刚在App.config中将maxReceivedMessageSize和maxBufferSize的值增加到65536000(我公然在最后添加了三个零)(后者因为它在ArgumentException中抱怨“For TransferMode.Buffered,MaxReceivedMessageSize和MaxBufferSize必须是相同的值。 参数名称:bindingElement“)。
现在我可以收到更大的回复...
直到我达到另一个限制(我认为)之后,在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设置是否有限制?
答案 0 :(得分:3)
我猜你正在使用Windows身份验证因此而不是一条消息,解释你是如何破坏你的消息限制的。当您通过Windows Authenticated请求发送时,WCF发送SOAP请求两次,一次失败并返回一个接受标头,第二次发送带有Windows身份验证标头。
但是,从我的测试来看,如果邮件真的失败了,看起来你仍然会得到401.
要解决此问题,我必须将服务器跟踪日志记录放入:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel" switchValue="Critical, Error, Warning">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Logs\ServiceTrace.svclog"/>
</listeners>
</source>
</sources>
</system.diagnostics>
然后,我必须加入更大的读者配额,如上所述(但我使用较小的值):
然后,您通常需要设置自定义行为以增加对象图中的最大项目数:
<behaviors>
<serviceBehaviors>
<behavior name="MaximumItemsBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
您需要在“<system.serviceModel><services><service>
”元素中添加“behaviourConfiguration”属性,其值为“MaximumItemsBehaviour”。
我读过的其他建议,但不需要自己就是补充:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime maxRequestLength="2097151" />
</system.web>
和
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="209715200"/>
</requestFiltering>
</security>
</system.webServer>
答案 1 :(得分:0)
在客户端查看readerQuotas,如果你想要TLDR版本 - 看看这确实是你的问题,你可以设置max(Int32.MaxValue),如下所示。
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />