当内容长度超过64k时,将二进制数据流传输到WCF休息服务给出错误请求(400)

时间:2011-01-10 02:47:04

标签: wcf rest httpwebrequest

我有一个接收流的WCF服务:

[ServiceContract]
public class UploadService : BaseService
{
    [OperationContract]
    [WebInvoke(BodyStyle=WebMessageBodyStyle.Bare, Method=WebRequestMethods.Http.Post)]
    public void Upload(Stream data)
    {
        // etc.         
    }
}

此方法允许我的Silverlight应用程序上传大型二进制文件,最简单的方法是从客户端手工制作HTTP请求。以下是Silverlight客户端中执行此操作的代码:

const int contentLength = 64 * 1024;  // 64 Kb

var request = (HttpWebRequest)WebRequest.Create("http://localhost:8732/UploadService/");
request.AllowWriteStreamBuffering = false;
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "application/octet-stream";
request.ContentLength = contentLength;
using (var outputStream = request.GetRequestStream())
{
     outputStream.Write(new byte[contentLength], 0, contentLength);
     outputStream.Flush();
     using (var response = request.GetResponse());
}

现在,在上面的例子中,我正在流式传输64 kB数据(或更少),这个正常工作,如果我在WCF方法中设置断点,我可以检查流并看到64 kB的零值 - yay!

如果我发送超过64 kB的数据,就会出现问题,例如将我的客户代码的第一行更改为以下内容:

const int contentLength = 64 * 1024 + 1; // 64 kB + 1 B

当我调用request.GetResponse()时,这会在客户端上引发异常:

  

远程服务器返回错误:   (400)不良请求。

在服务器的WCF配置中,我将maxReceivedMessageSize,maxBufferSize和maxBufferPoolSize设置为2147483647,但无济于事。以下是我服务的app.config中的相关部分:

<service name="UploadService">
    <endpoint address="" 
              binding="webHttpBinding" 
              bindingName="StreamedRequestWebBinding"
              contract="UploadService" 
              behaviorConfiguration="webBehavior">
        <identity>
            <dns value="localhost" />
        </identity>
    </endpoint>
    <host>
        <baseAddresses>
            <add baseAddress="http://localhost:8732/UploadService/" />
       </baseAddresses>
    </host>       
</service>

<bindings>
    <webHttpBinding>
        <binding name="StreamedRequestWebBinding" 
                 bypassProxyOnLocal="true"
                 useDefaultWebProxy="false"
                 hostNameComparisonMode="WeakWildcard"
                 sendTimeout="00:05:00"
                 openTimeout="00:05:00"
                 receiveTimeout="00:05:00"
                 maxReceivedMessageSize="2147483647"
                 maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 transferMode="StreamedRequest">
            <readerQuotas maxArrayLength="2147483647"
                          maxStringContentLength="2147483647" />
        </binding>
    </webHttpBinding>
</bindings>

<behaviors>
    <endpointBehaviors>
        <behavior name="webBehavior">
            <webHttp />
        </behavior>
    <endpointBehaviors>
</behaviors>

如何让我的服务接受超过64 kB的流式数据?

编辑:如上面的客户端代码所示,我没有使用服务引用,而是手动构建HTTP请求。 (这是因为Silverlight服务引用不支持流。)

2 个答案:

答案 0 :(得分:5)

所以我发现了问题 - bindingName="StreamedRequestWebBinding"应该是bindingConfiguration="StreamedRequestWebBinding"。对于前者,我指定的绑定配置根本没有被使用,因此maxReceivedMessageSize默认为64kB。

答案 1 :(得分:0)

您的Silverlight应用中还有一个ServiceReferences.ClientConfig文件,您应该更新该配置中的maxBufferSizemaxReceivedMessageSize