通过WCF服务的大文件

时间:2012-03-14 01:54:39

标签: c# wcf large-data-volumes

类似的问题在流淌,我看着他们所有人。似乎没有解决我的问题。

- 更新: -

我正在尝试使用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)时,我得到一个例外:

  

格式化程序在尝试反序列化时抛出异常   消息:反序列化操作的请求消息正文时出错   'DocumentInsert'。已经有最大数组长度配额(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'。 :抛出我在一开始写的异常。

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

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

上的MSDN文章

答案 1 :(得分:0)

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

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

不幸的是,根据我提供的信息,你们不会看到它。