Asp.net WCF响应太长-身份验证错误

Asp.net WCF响应太长-身份验证错误,asp.net,wcf,windows-authentication,communicationexception,Asp.net,Wcf,Windows Authentication,Communicationexception,在我目前工作的项目中,公开了一个WCF服务,它返回一个业务实体数组,我们称之为Invoice: Invoice[] GetInvoicesByTypeAndTime(InvoiceType invoiceType, byte startHour, byte? endHour); 使用的身份验证机制是Windows身份验证,WCF服务托管在IIS 6上托管的Web应用程序中 起初,当我获取超过64kB的数据时,抛出了一个CommunicationException,指出“已超过传入消息的最大消息

在我目前工作的项目中,公开了一个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中抱怨“对于TransferMode.Buffered,maxReceivedMessageSize和maxBufferSize必须是相同的值。 参数名称:bindingElement“)

现在我可以收到更多的回复

直到我达到另一个极限(我想),在624个元素(大约2.2MB)之后,会抛出一个奇怪的异常:

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设置是否有限制?

在客户端查看一下,如果您想要TLDR版本-要查看这是否确实是您的问题,您可以设置最大值(Int32.MaxValue),如下所示

<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

我猜您使用的是Windows身份验证,因此是401,而不是一条解释您如何突破消息限制的消息。当您通过Windows身份验证请求发送时,WCF会发送SOAP请求两次,一次失败并返回accepts标头,第二次与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>

您需要向“
”元素添加一个值为“MaximumItemsBehaviour”的“行为配置”属性

我读过的其他建议,但我并不需要自己补充:

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpRuntime maxRequestLength="2097151" />
  </system.web>

以及:



感谢Yannick M.重新格式化:)感谢bnkdev指出这一点,并尝试了它,但它无法修复:(
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="209715200"/>
      </requestFiltering>
    </security>
  </system.webServer>