简体   繁体   English

通过WCF服务的大文件

[英]large file through WCF service

Similar questions are flowing around and I looked at all of them. 类似的问题不断涌现,我查看了所有这些问题。 It appears none solve my issue. 看来没有人能解决我的问题。

-- UPDATE: -- -更新:-

I am trying to upload a document (pdf, doc, or whatever) to a database using WCF Service. 我正在尝试使用WCF服务将文档(pdf,doc或其他文件)上传到数据库。 The call to the service looks like this: 对该服务的调用如下所示:

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

Here is signature for the contract: 这是合同的签字:

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

Please note that I am passing byte array for the content as this is what needs to be passed to store things in DB. 请注意,我正在传递内容的字节数组,因为这是将内容存储在DB中需要传递的内容。

-- End of Update -- -更新结束-

I can successfully upload a small file (couple kb). 我可以成功上传一个小文件(kb)。 However, when I try to upload something larger (20kb), I get an Exception: 但是,当我尝试上传更大的内容(20kb)时,出现异常:

The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'DocumentInsert'. 格式化程序尝试反序列化消息时引发异常:反序列化“ DocumentInsert”操作的请求消息正文时出错。 The maximum array length quota (16384) has been exceeded while reading XML data. 读取XML数据时,已超出最大数组长度配额(16384)。 This quota may be increased by changing the MaxArrayLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. 通过更改在创建XML阅读器时使用的XmlDictionaryReaderQuotas对象上的MaxArrayLength属性,可以增加此配额。 Line 1, position 31774. 第1行,位置31774。

The error seems to be obvious... just go and increase the MaxArrayLength. 该错误似乎很明显...只需增加MaxArrayLength。 I have done that without any successful result. 我这样做没有任何成功的结果。 Below are the relevant parts from my web.configs 以下是我的web.configs中的相关部分

Client: 客户:

<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>

Service: 服务:

<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>

Attaching diagnostics shows: 附加诊断显示:

  • Construct Service : no errors/warnings 构造服务 :无错误/警告
  • Open Service : warning - Configuration evaluation context not found - No matching tag was found. 开放服务 :警告-找不到配置评估上下文-找不到匹配的标签。 Default endpoints added. 添加了默认端点。
  • Listen at 'http://dev.svc.someurl.com/CommonService.svc' : no errors/warnings 收听“ http://dev.svc.someurl.com/CommonService.svc” :无错误/警告
  • Processing message 1 : no errors/warnings 处理消息1 :无错误/警告
  • Processing Action 'http://tempuri.org/ICommonService/DocumentInsert'. 处理动作“ http://tempuri.org/ICommonService/DocumentInsert”。 : throws exception that I wrote at the very beginning. :抛出我一开始就写的异常。

Any help is appreciated. 任何帮助表示赞赏。

I have came across with the same exception a few months ago. 几个月前,我遇到了同样的例外。 To send/receive large data to/from WCF service you have to set transferMode="Streamed" . 要向/从WCF服务发送/接收大数据,必须设置transferMode="Streamed" When use transfermode as Buffered, it actually puts the entire file in memory before uploading/downloading. 当将transfermode用作Buffered时,实际上是在上载/下载之前将整个文件放入内存中。 Therefore a large buffer is required on both the web client and the WCF service host.Whereas Streamed transfers can improve the scalability of a service by eliminating the need for large memory buffers. 因此,Web客户端和WCF服务主机上都需要大缓冲区。而流传输可以通过消除对大内存缓冲区的需求来提高服务的可伸缩性。 For more information on transfermode, see the MSDN article on TransferMode Enumeration 有关transfermode的更多信息,请参见TransferMode枚举上的MSDN文章。

All right, after a day of struggling I finally found an issue. 好吧,经过一天的挣扎,我终于找到了一个问题。 I just had to make sure that the name of the tag in WCF web.config matches the namespace and the name of the service: 我只需要确保WCF web.config中的标记名称与名称空间和服务名称匹配即可:

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

Unfortunately it was not something that you guys would see based on the information that I provided. 不幸的是,根据我提供的信息,你们不会看到这些东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM