wcf 服务错误请求 400 流式传输

Posted

技术标签:

【中文标题】wcf 服务错误请求 400 流式传输【英文标题】:wcf service bad request 400 streaming 【发布时间】:2013-11-24 09:59:00 【问题描述】:

我正在开发一个 wcf 服务,将 xml 文件上传到存储数据库, 出于这个原因,我正在压缩文件,将其保存到内存流并使用 PushData(Stream as MemoryStream) 将其传递给服务 不幸的是,我无法让它工作。看来我有一些配置丢失或错误。 我在 iis 8.0 上将服务托管在 storageservice.svc 中作为自托管 错误消息是:400 错误请求

这是我的配置文件

客户端应用配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
          <binding name="BasicHttpBinding_IStorageService"     maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed"  receiveTimeout="00:10:00">
            <security mode="None"/>
          </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://10.5.1.6:8001/StorageService.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IStorageService"
           name="BasicHttpBinding" contract="StorageService.IStorageService" />
    </client>
</system.serviceModel>
</configuration>

服务器端网络配置

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.web>
    <compilation debug="true" />
    <httpRuntime maxRequestLength="2147483647"/>
    </system.web>
    <system.serviceModel>
    <services>
      <service name="Namespace.StorageService">
        <endpoint address="" binding="basicHttpBinding" contract="Namespace.IStorageService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://10.5.1.6:8001/" />
            <add baseAddress="net.tcp://10.5.1.6:10001/" />
          </baseAddresses>
        </host>
    </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>       
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
     <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBinding" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed"  receiveTimeout="00:10:00" >
          <security mode="None"/>
        </binding>
      </basicHttpBinding>
    </bindings>
<protocolMapping>
      <add binding="basicHttpBinding" scheme="http"/>
    </protocolMapping>
  </system.serviceModel>
</configuration>

我真的需要帮助,尝试了 3 天才弄明白......所有的缓冲区大小都没有帮助

尝试过的解决方案:

    在绑定中添加 readerquotas 元素 使用 Mtom 消息编码 启用跟踪(不幸的是没有做任何事情)

编辑:客户端方法

  Using client As New StorageService.StorageServiceClient
            client.Open()
            Dim helper As CirrostratusHelper = New CirrostratusHelper
            Dim data As CirrostratusStorage = helper.GenerateData()
            Dim gdata = data.GenerateData
            For Each item In gdata
                Try
                    Dim memorystream As New MemoryStream
                    Dim databasedaata As ZipArchive = item.Value.DatabaseData
                    databasedaata.Save(memorystream)
                    memorystream.Seek(0, SeekOrigin.Begin)
                  ' this method produces the bad exception '
                    client.PushData(memorystream)
                Catch ex As Exception                  
                    Dim test = ex.Message & ex.StackTrace
                End Try
            Next
            client.Close()
        End Using

服务方式:

   Public Function PushData(DataStream As Stream) As Boolean Implements IStorageService.PushData
      Const buffersize As Integer = 2048
            Dim buffer(buffersize) As Byte
            Dim bytesread As Integer = bytesread = DataStream.Read(buffer, 0, buffersize)
            Dim DataMemoryStream As New MemoryStream
            While bytesread > 0
                bytesread = DataStream.Read(buffer, 0, buffersize)
                DataMemoryStream.Write(buffer, 0, buffersize)
            End While
            DataMemoryStream.Seek(0, SeekOrigin.Begin)
            Dim zip As ZipArchive = ZipArchive.Read(DataMemoryStream)
              '...'
    end function

【问题讨论】:

附加信息:我想发送的文件约为 20 MB 我看不出配置有问题。向上传输 xml 的函数是什么样的? 另一个问题......如果您从客户端上传到存储服务器,为什么要流式传输而不是缓冲?流式传输所涉及的代码比缓冲要复杂得多。 我阅读了一些关于使用流媒体处理大量数据的博客,我们有时需要发送 3 GB 的数据...... 好的,是的,使用 3 GB,您可能只想流式传输,因为您可能会在整个缓冲之前耗尽内存。发布您用于上传流的代码,以便我们查看。 【参考方案1】:

我发现了问题, 这是关于绑定的命名,我忘了让端点使用绑定配置

<bindings>
  <basicHttpBinding>
    <binding name="basicHttpBinding_Storage" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed"  receiveTimeout="00:10:00" >
      <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxStringContentLength="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647"/>
      <security mode="None"/>
    </binding>
  </basicHttpBinding>
</bindings>
 <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_Storage" contract="DynaMed.IStorageService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>

【讨论】:

以上是关于wcf 服务错误请求 400 流式传输的主要内容,如果未能解决你的问题,请参考以下文章

WCF:使用带有消息契约的流式传输

WCF - 远程服务器返回意外响应:(400)错误请求

WCF:自托管服务上的 HTTP 400 错误请求

WCF REST 服务 400 错误请求

WCF 流式传输错误(最大邮件大小配额)

尝试使用 XHR 联系 WCF 服务时出现 400 错误请求