【问题标题】:bug when try to send file in wcf尝试在 wcf 中发送文件时出现错误
【发布时间】:2026-01-07 21:20:03
【问题描述】:

当我尝试使用 WCF 服务发送文件时,我得到了这个异常

格式化程序抛出异常,而 试图反序列化消息: 反序列化请求正文时出错 操作“Send_File”的消息。这 最大数组长度配额 (16384) 有 读取 XML 数据时超出。 此配额可能会增加 更改 MaxArrayLength 属性 在 XmlDictionaryReaderQuotas 创建 XML 时使用的对象 阅读器。

在发送之前,我首先将文件转换为字节数组 这是发送文件的客户端配置

<system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="TcpBinding" closeTimeout="10:00:00" openTimeout="10:00:00"
        receiveTimeout="10:00:00" sendTimeout="10:00:00" transactionFlow="false"
        transferMode="Buffered" transactionProtocol="OleTransactions"
        hostNameComparisonMode="StrongWildcard" listenBacklog="10"
        maxBufferPoolSize="10000000" maxBufferSize="10000000" maxConnections="30"
        maxReceivedMessageSize="10000000">
      <readerQuotas maxDepth="64" maxStringContentLength="10000000" maxArrayLength="100000000"
          maxBytesPerRead="10000000" maxNameTableCharCount="10000000" />
      <reliableSession ordered="true" inactivityTimeout="10:00:00"
          enabled="false" />
    </binding>
  </netTcpBinding>
  <wsDualHttpBinding>
    <binding name="HttpBinding" closeTimeout="10:00:00" openTimeout="10:00:00"
        receiveTimeout="10:00:00" sendTimeout="10:00:00" bypassProxyOnLocal="false"
        transactionFlow="false" hostNameComparisonMode="StrongWildcard"
        maxBufferPoolSize="10000000" maxReceivedMessageSize="10000000"
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="10000000" maxArrayLength="10000000"
          maxBytesPerRead="10000000" maxNameTableCharCount="10000000" />
      <reliableSession ordered="true" inactivityTimeout="10:00:00" />
    </binding>
  </wsDualHttpBinding>
</bindings>
<behaviors>
  <endpointBehaviors>
    <behavior name="filebehavior">
      <dataContractSerializer maxItemsInObjectGraph="2000000000"/>
    </behavior>
  </endpointBehaviors>
</behaviors>
<client>
  <endpoint address="net.tcp://localhost:8000/ChatRoom/service" behaviorConfiguration="filebehavior"
      binding="netTcpBinding" bindingConfiguration="TcpBinding"
      contract="ChatRoom" name="TcpBinding">
    <identity>
      <servicePrincipalName value="my_machine\ASPNET" />
    </identity>
  </endpoint>
  <endpoint address="http://localhost:8001/ChatRoom/service" binding="wsDualHttpBinding"
      bindingConfiguration="HttpBinding" contract="ChatRoom" name="HttpBinding">
    <identity>
      <servicePrincipalName value="my_machine\ASPNET" />
    </identity>
  </endpoint>
</client>

服务器配置

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="securingWSHttpBinding">
        </binding>
        <binding name="wsHttpBinding_ChatRoomServices" maxReceivedMessageSize="10000000" />
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceTimeouts transactionTimeout="10:00:00"/>
          <serviceMetadata httpGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
        <services>
      <service name="ChatRoomService.ChatRoom"
               behaviorConfiguration="ServiceBehavior">
        <endpoint address="service" binding="netTcpBinding" contract="ChatRoomService.IChatRoom" name="TcpBinding"/>
        <endpoint address="service" binding="wsDualHttpBinding" contract="ChatRoomService.IChatRoom" name="HttpBinding"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" name="MexBinding"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8000/ChatRoom/"/>
            <add baseAddress="http://localhost:8001/ChatRoom/"/>
          </baseAddresses>
        </host>
      </service>
        </services>
    </system.serviceModel>

我该如何解决这个异常?

【问题讨论】:

  • 您是否在客户端和/或服务中设置端点以使用上述绑定与端点元素中的 bindingConifguration 属性?如果不是,WCF 将使用绑定的默认值。
  • 我添加了端点

标签: c# wcf file-transfer nettcpbinding


【解决方案1】:

在指定服务行为和端点行为时添加此项

在客户端,指定端点时,设置行为名称:

<endpoint behaviorConfiguration = "myBehavior"/>

然后指定此行为:

<behaviours>
    <endpointBehaviors>
        <behavior name="myBehavior">
            <dataContractSerializer maxItemsInObjectGraph="a number that is big enough"/>
        </behavior>
    </endpointBehaviors>
</behaviors>

在服务器上:

当你指定'service'和'endpoint'时,分别附加一个serviceBehavior和endpointBehavior,就像客户端一样。

【讨论】:

  • 您可能想要修改服务的配置文件,而不是客户端的 - 至少,在我调整哪个配置之前,我遇到了 maxStringContentLength 问题。此外,为了防止任何混淆,maxItemsInObjectGraph 的值需要是一个足够大的数字,以便您发送的内容 - 不要使用文字字符串“足够大的数字”作为值。
  • @lockstock 我应该在客户端或服务器的哪个位置添加它?
  • @Tim 我没看懂这部分你可能想修改服务的配置文件,而不是客户端的我在哪里可以找到服务的配置文件?
  • 感谢您的澄清,我以为萨拉蒙蒂会解决这个问题。最好指定一个与您需要一样大的值,以避免潜在的安全问题,例如拒绝服务攻击。
  • @salamonti - 服务的配置文件应该与服务的主机一起(在 IIS 中,它将是 web.config,对于 Windows 服务或自托管服务,它将是 app.config) .
【解决方案2】:

首先,您的绑定甚至在客户端和服务器之间都不匹配 :)

您的客户端有一个 NetTcpBinding 和一个 DualWsHttpBinding,而您的服务器有一个 wsHttpBinding。老实说,我很惊讶他们甚至可以相互交流。 (除非您使用的是 WCF 4.0,在这种情况下您将拥有默认绑定和端点)。

其次,您的服务配置文件没有引用 delared 绑定 - 端点上没有 bindingConfiguration 属性,因此如果建立通信,通道将使用指定绑定协议的默认值。

客户端配置看起来不错,在服务器上试试这个(我只包括 NetTcpBinding 协议,并将 behaviorName 和 bindingConfiguration 属性添加到端点 - 其他绑定类似):

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="TcpBinding" closeTimeout="10:00:00" openTimeout="10:00:00" receiveTimeout="10:00:00" sendTimeout="10:00:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="10000000" maxBufferSize="10000000" maxConnections="30" maxReceivedMessageSize="10000000">
        <readerQuotas maxDepth="64" maxStringContentLength="10000000" maxArrayLength="100000000" maxBytesPerRead="10000000" maxNameTableCharCount="10000000" />       
        <reliableSession ordered="true" inactivityTimeout="10:00:00" enabled="false" />     
      </binding>
    </netTcpBinding>
  </bindings> 
  <behaviors>
    <endpointBehaviors>
      <behavior name="filebehavior">       
        <dataContractSerializer maxItemsInObjectGraph="2000000000"/>     
      </behavior>
    </endpointBehaviors> 
  </behaviors> 
  <service>
    <endpoint address="net.tcp://localhost:8000/ChatRoom/service" behaviorConfiguration="filebehavior" binding="netTcpBinding" bindingConfiguration="TcpBinding" contract="ChatRoom" name="TcpBinding">
      <identity>
        <servicePrincipalName value="my_machine\ASPNET" />
      </identity>
    </endpoint>    
  </service>
</system.serviceModel>

【讨论】:

    【解决方案3】:

    您可能想在您的情况下尝试流式传输模式。 http://msdn.microsoft.com/en-us/library/ms789010.aspx

    【讨论】:

      最近更新 更多