【问题标题】:large file through WCF service通过 WCF 服务的大文件
【发布时间】:2012-03-30 11:52:52
【问题描述】:

类似的问题不断涌现,我查看了所有问题。似乎没有一个能解决我的问题。

-- 更新:--

我正在尝试使用 WCF 服务将文档(pdf、doc 或其他)上传到数据库。 对服务的调用如下所示:

using (var cw = new WCFClientWrapper<ICommonService>())
{
    cw.Channel.DocumentInsert(content, filename, contentType);
}

这是合同的签名:

[OperationContract]
void DocumentInsert(byte[] content, string fileName, string contentType);

请注意,我正在为内容传递字节数组,因为这是在 DB 中存储内容时需要传递的内容。

-- 更新结束--

我可以成功上传一个小文件(几 kb)。但是,当我尝试上传更大的内容(20kb)时,我得到一个异常:

格式化程序在尝试反序列化 消息:反序列化操作请求消息正文时出错 '文档插入'。最大数组长度配额 (16384) 已 读取 XML 数据时超出。此配额可能会增加 更改 XmlDictionaryReaderQuotas 上的 MaxArrayLength 属性 创建 XML 阅读器时使用的对象。第 1 行,位置 31774。

错误似乎很明显......只需增加 MaxArrayLength。我这样做了,但没有任何成功的结果。以下是我的 web.configs 中的相关部分

客户:

<system.serviceModel>

    <behaviors>
      <endpointBehaviors>
        <behavior name="SecureBehavior">
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <binding name="WSHttpBinding_Service" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="262144" messageEncoding="Text"
          textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="2147483646" maxBytesPerRead="4096" maxNameTableCharCount="5242880" />
        </binding>
      </basicHttpBinding>
    </bindings>

    <client>
      <endpoint address="http://dev.svc.someurl.com/CommonService.svc"
                binding="basicHttpBinding"
                bindingConfiguration="WSHttpBinding_Service"
                behaviorConfiguration="SecureBehavior"
                contract="MyApp.Contracts.ServiceContracts.ICommonService"
                name="MyApp.Contracts.ServiceContracts.ICommonService">
      </endpoint>
    </client>

  </system.serviceModel>

服务:

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- 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>

    <bindings>
      <basicHttpBinding>
        <binding name="MyBasicHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service name="MyApp.WCFServices.CommonService">
        <endpoint address=""
                  binding="basicHttpBinding"
                  bindingConfiguration="MyBasicHttpBinding"
                  contract="MyApp.Contracts.ServiceContracts.ICommonService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
      <service name="MyApp.WCFServices.AccountService">
        <endpoint address=""
                  binding="basicHttpBinding"
                  bindingConfiguration="MyBasicHttpBinding"
                  contract="MyApp.Contracts.ServiceContracts.IAccountService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

附加诊断显示:

  • 构造服务:没有错误/警告
  • 打开服务:警告 - 未找到配置评估上下文 - 未找到匹配标记。添加了默认端点。
  • 在 'http://dev.svc.someurl.com/CommonService.svc' 上收听:没有 错误/警告
  • 处理消息 1:没有错误/警告
  • 处理操作“http://tempuri.org/ICommonService/DocumentInsert”。 : 抛出我一开始写的异常。

感谢任何帮助。

【问题讨论】:

    标签: c# wcf large-data-volumes


    【解决方案1】:

    几个月前我遇到了同样的例外。要向 WCF 服务发送/接收大数据,您必须设置 transferMode="Streamed"。当使用传输模式作为缓冲时,它实际上在上传/下载之前将整个文件放入内存中。因此,Web 客户端和 WCF 服务主机都需要一个大缓冲区。而流传输可以通过消除对大内存缓冲区的需要来提高服务的可伸缩性。有关传输模式的更多信息,请参阅 TransferMode Enumeration 上的 MSDN 文章

    【讨论】:

    • 感谢您的建议。虽然没有帮助。在我看来,它只是忽略了我的绑定并使用了默认绑定。我不确定为什么或如何
    【解决方案2】:

    好吧,经过一天的努力,我终于找到了一个问题。 我只需要确保 WCF web.config 中的标记名称与命名空间和服务名称匹配:

    <service name="ServicesImplementation.WcfServices.CommonService">
    

    很遗憾,根据我提供的信息,你们不会看到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 2019-05-25
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多