当我用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相关问答推荐

如何从 JavaScript 调用 C# 函数?

如何使多行的 TextBox 控件无法调整大小?

将 NUnit 添加到 ASP.NET MVC 测试框架的选项中

创建一个供 ASP.NET 应用程序中的所有线程使用的静态 Regex 对象是否有效?

'Access-Control-Allow-Origin' 标头包含多个值 '*, *',但只允许一个

ASP.Net - App_Data & App_Code 文件夹?

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

解析器错误消息:文件/TestSite/Default.aspx.cs不存在

System.Web.Helpers.Crypto - 盐在哪里?

HttpContext.Current.Request.IsAuthenticated 和 HttpContext.Current.User.Identity.IsAuthenticated 有什么区别?

为什么对 ASP.NET MVC 控制器的调用不执行 DelegatingHandler?

来自 IP 地址的经度和纬度值

如何将 ASP.NET MVC5 身份验证添加到现有数据库

使下拉列表项不可 Select

如何以编程方式将标签的前景色设置为其默认值?

如何从 ASP.Net 发布然后重定向到外部 URL?

什么时候应该使用 Response.Redirect(url, true)?

HtmlAgilityPack Select 的子 node 不符合预期

远程计算机无法连接到 Visual Studio Web 服务器

协调 ASP.NET 脚本包和源映射