WCF REST上传文件(一些文件成功 - 200,一些失败 - 400错误请求)

时间:2011-04-19 05:54:11

标签: wcf flex actionscript-3 rest filereference

这是我的WCF REST端点:

[WebInvoke(Method = "POST", UriTemplate = "_test/upload")]
public void UploadImage(Stream data)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.OK;
    try
    {
        var parser = new MultipartParser(data);
        var ext = Path.GetExtension(parser.Filename);
        var filename = string.Format("{0}{1}", Guid.NewGuid().ToString("N"), ext);
        var folder = HttpContext.Current.Server.MapPath(@"~\Uploads\");
        var filepath = Path.Combine(folder, filename);
        File.WriteAllBytes(filepath, parser.FileContents);
    }
    catch (Exception)
    {
        WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
    }
}

我正在使用此处的多部分解析器:http://antscode.blogspot.com/2009/11/parsing-multipart-form-data-in-wcf.html

我的问题是上面的内容适用于某些文件(.bat,.txt,.cs,.doc) - 我在Fiddler中看到所有好的迹象,包括200(OK)状态。

当我尝试上传其他文件(.xls,.vsd)时,它会因400(错误请求)状态而失败。我很惊讶.doc会起作用,而.xls和.vsd会失败。

它也是一致的。我已经成功上传了几个.doc文件而没有任何失败。我还试图上传几个.xls文件 - 一些成功,一些失败(成功一遍又一遍,失败一遍又一遍)。当我写这个并测试越来越多的文件时,有一个.pdf文件始终产生504(Fiddler - Receive Failure)错误。

仅供参考,我在客户端使用Flex并使用FileReference类进行上传。 Flex代码是标准的 - 使用此代码,唯一的变化是WCF REST URL:http://blog.flexexamples.com/2007/09/21/uploading-files-in-flex-using-the-filereference-class/

为什么我看到一些失败和一些成功的想法?我没看到两者的区别?

提前致谢。

1 个答案:

答案 0 :(得分:2)

您可以检查成功文件的大小,并在web.config中调整webHttpBinding的maxReceivedMessageSize。它默认只有64KB。我遇到了类似的问题,直到我提高它(这里乘以1000)。同时将requestValidationMode设置为2.0,将pages.validateRequest设置为false,以防止阻止“危险”上传。

这些更改让我有所帮助,但是我遇到了大约4MB的文件(无论maxReceivedMessageSize设置如何);修复需要增加httpRuntime的maxRequestLength。

我将transferMode设置为StreamedRequest,但我不确定以这种方式上传文件对于IIS性能和/或拒绝服务攻击的影响。我认为流媒体模式应该相当安全。这是关于Large Data and Streaming的一篇不错的MSDN文章。我之前使用过分块客户端来避免像这样的巨大请求。

<system.web>
    <httpRuntime requestValidationMode="2.0" maxRequestLength="65536000" />
    <pages validateRequest="false" />

<!-- (etc.) -->
</system.web>
<!-- (etc.) -->
<system.serviceModel>
     <bindings>
         <webHttpBinding>
             <binding maxReceivedMessageSize="65536000" transferMode="StreamedRequest">
                <security mode="None" />
              </binding>
         </webHttpBinding>
    </bindings>
</system.serviceModel>