当我用ASP将大文件上传到我的web api时.NET内核,在我处理和存储上传的函数启动之前,运行时会将文件加载到内存中.对于大型上传,这会成为一个问题,因为它既慢又需要更多内存.对于以前版本的ASP.NET there are some articles关于如何禁用请求缓冲,但我找不到任何关于如何使用ASP实现这一点的信息.净核心.有没有可能禁用请求缓冲,这样我就不会一直耗尽服务器上的内存?

推荐答案

使用Microsoft.AspNetCore.WebUtilities.MultipartReader,因为它...

可以用最小的缓冲来解析任何流.它一次给你每个部分的标题和正文,然后你可以对该部分的正文做你想做的事情(缓冲、丢弃、写入磁盘等等).

下面是一个中间件示例.

app.Use(async (context, next) =>
{
    if (!IsMultipartContentType(context.Request.ContentType))
    {
        await next();
        return;
    }

    var boundary = GetBoundary(context.Request.ContentType);
    var reader = new MultipartReader(boundary, context.Request.Body);
    var section = await reader.ReadNextSectionAsync();

    while (section != null)
    {
        // process each image
        const int chunkSize = 1024;
        var buffer = new byte[chunkSize];
        var bytesRead = 0;
        var fileName = GetFileName(section.ContentDisposition);

        using (var stream = new FileStream(fileName, FileMode.Append))
        {
            do
            {
                bytesRead = await section.Body.ReadAsync(buffer, 0, buffer.Length);
                stream.Write(buffer, 0, bytesRead);

            } while (bytesRead > 0);
        }

        section = await reader.ReadNextSectionAsync();
    }

    context.Response.WriteAsync("Done.");
});

这是帮手.

private static bool IsMultipartContentType(string contentType)
{
    return 
        !string.IsNullOrEmpty(contentType) &&
        contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0;
}

private static string GetBoundary(string contentType)
{
    var elements = contentType.Split(' ');
    var element = elements.Where(entry => entry.StartsWith("boundary=")).First();
    var boundary = element.Substring("boundary=".Length);
    // Remove quotes
    if (boundary.Length >= 2 && boundary[0] == '"' && 
        boundary[boundary.Length - 1] == '"')
    {
        boundary = boundary.Substring(1, boundary.Length - 2);
    }
    return boundary;
}

private string GetFileName(string contentDisposition)
{
    return contentDisposition
        .Split(';')
        .SingleOrDefault(part => part.Contains("filename"))
        .Split('=')
        .Last()
        .Trim('"');
}

外部参照

Asp.net相关问答推荐

IIS重写模块排除机器人但允许GoogleBot

无法在Microsoft Windows Server 2016(数据中心)上运行.NET可移植性分析器

ASP.NET多行查询文本框中的多个名称并将结果添加到单个网格视图

Stimulsoft 没有在智能手机中显示正确的 pdf 字体

强制从 /bin 而不是 GAC 加载程序集?

ASP .Net Web API 将图像下载为二进制

HttpResponse 的区别:SetCookie、AppendCookie、Cookies.Add

ASP.NET Core 1.0 ConfigurationBuilder().AddJsonFile("appsettings.json");找不到文件

使用 IIS 的 ASP.NET 调试超时

将 ListItem 的 ASP.NET 列表数据绑定到 DropDownList 问题

使用 JSON.NET 解析 json 字符串

对于每个请求,RestClient 应该是单例还是新的

在 ASP.NET 中实现 404 的最佳方法

如何在 ASP.NET Core Web API 中配置 JSON 格式的缩进

如何在实体框架中添加表?

如何将参数传递给 ASP.NET MVC 2 中的自定义 ActionFilter?

HttpContext.Current.Request.Url.Host 它返回什么?

ASP.NET 5、EF 7 和 SQLite - SQLite 错误 1:没有这样的表:博客

ASP.NET 身份提供程序 SignInManager 不断返回失败

System.Drawing.Image.FromFile() 上的内存不足异常