c# - 使用 WebAPI 流式传输大文件(通过 IIS 超过 2GB)

标签 c# asp.net asp.net-web-api

我正在尝试将非常大的文件 (>2GB) 上传到我的 WebAPI 应用程序(在 .NET 4.5.2、Windows 2012R2 上运行)。

设置 httpRuntime maxRequestLength 属性没有用,因为它只适用于小于 2GB 的文件。

我目前正在使用自定义 MultipartFormDataStreamProvider 来读取服务器上的整个流,并且我已经使用自定义 WebHostBufferPolicySelector 关闭了缓冲。

我发现 ASP.NET(或与此相关的 WebAPI)在底层使用 HttpBufferlessInputStream,它有一个名为 _disableMaxRequestLength 的字段。如果我将此值设置为 true(通过反射),我可以流式传输任何大小的文件。

然而,摆弄这些内部结构显然不是一个好方法。

用于请求的 HttpRequest 类有一个名为 GetBufferlessInputStream 的方法它有一个允许禁用 maxRequestLength 的重载。

我的问题是:如何让 WebAPI 使用此重载而不是标准重载?

有什么方法可以替换默认的 HttpRequest 或 HttpContext 类吗?或者我真的需要对所有内容使用反射吗?

这是我目前用来禁用 maxRequestLength 的代码:

    private void DisableRequestLengthOnStream(HttpContent parent)
    {
        var streamContentProperty = parent.GetType().GetProperty("StreamContent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        if (streamContentProperty == null) return;
        var streamContent = streamContentProperty.GetValue(parent, null);
        if (streamContent == null) return;
        var contentProperty = typeof(StreamContent).GetField("content", BindingFlags.Instance | BindingFlags.NonPublic);
        if (contentProperty == null) return;
        var content = contentProperty.GetValue(streamContent);
        if (content == null) return;
        var requestLengthField = content.GetType().GetField("_disableMaxRequestLength", BindingFlags.Instance | BindingFlags.NonPublic);
        if (requestLengthField == null) return;
        requestLengthField.SetValue(content, true);
    }

最佳答案

好的,我找到了一个非常简单的解决方案。来自@JustinR 的回答。当然可以。但我想继续使用 MultipartFormDataStreamProvider,因为它可以处理所有 MIME 内容。

解决方案是使用正确的无缓冲输入流简单地创建一个新的 StreamContent 实例,并用原始内容的 header 填充它:

var provider = new MultipartFormDataStreamProvider(path);
var content = new StreamContent(HttpContext.Current.Request.GetBufferlessInputStream(true));
foreach (var header in Request.Content.Headers)
{
    content.Headers.TryAddWithoutValidation(header.Key, header.Value);
}

await content.ReadAsMultipartAsync(provider);

关于c# - 使用 WebAPI 流式传输大文件(通过 IIS 超过 2GB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25753248/

相关文章:

c# - c# 使用 linq 在一个属性上过滤两个列表

c# - 是否有更好的方法在 CLR 中验证 SqlXml?

c# - 如何高效地修剪数据

c# - 发送电子邮件的正确代码,asp.net

c# - 如何在 DB 和 ORM 中为已知和未知日期部分的混合设计出生日期

wcf - 不使用 WebAPI 的原因

c# - 这两个 LINQ 查询有什么区别?

c# - JQuery 自动完成调用中的撇号

c# - 在 Application_AquireRequestState 事件中用 POST 数据重写 Url

c# - 如何使用一次性对象对方法进行单元测试