代码之家  ›  专栏  ›  技术社区  ›  Andrei Rînea

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

  •  3
  • Andrei Rînea  · 技术社区  · 16 年前

    在我目前工作的项目中,公开了一个wcf服务,它返回一个业务实体数组,我们称之为invoice:

    Invoice[] GetInvoicesByTypeAndTime(InvoiceType invoiceType, byte startHour, byte? endHour);
    

    使用的身份验证机制是Windows身份验证,WCF服务托管在IIS 6上托管的Web应用程序中。

    最初,当我获取的数据超过64kb时,一个通信异常被抛出,说明“已超过传入消息(65536)的最大消息大小配额”。要增加配额,请在适当的绑定元素上使用maxReceivedMessageSize属性。”

    好吧,我只是在app.config中增加了maxReceivedMessageSize和maxBufferSize的值到65536000(我在结尾处公开添加了三个零)(后者是因为它在一个argumentexception中抱怨“对于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设置是否有限制?

    2 回复  |  直到 14 年前
        1
  •  3
  •   a-h    14 年前

    我猜您使用的是Windows身份验证,因此是401,而不是解释您如何突破消息限制的消息。当您通过Windows身份验证请求发送时,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> “具有”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>
    
        2
  •  0
  •   Ta01    16 年前

    看一看 readerQuotas 在客户机端,如果您希望TLDR版本-看看这是否确实是您的问题,您可以设置max(int32.maxValue),如下所示。

    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    
    推荐文章