从c#上传Azure大文件时出错,抛出“指定的阻止列表无效。”

问题描述 投票:0回答:1

我想使用 C# 在 Azure 容器中上传 blob。我在 UI(角度)中将 blob 分解为块,对于每个块,我调用我的 c# API。 这对于小文件来说效果很好。但对于大文件(甚至 130 MB),文件未完全上传,API 会抛出错误“指定的阻止列表无效。”

[HttpPost("{fileName}")]
public async Task<IActionResult> UploadChunk(string fileName, List<IFormFile> chunk)
{
    if (chunk.Count == 0)
    {
        return BadRequest("No file received from the request");
    }

    if (chunk.Count > 1)
    {
        return BadRequest("The request contains more than one file. Only one file can be uploaded at a time");
    }

    var blockBlobClient = blobContainerClient.GetBlockBlobClient(fileName);
    if (!await blockBlobClient.ExistsAsync())
    {
        await blockBlobClient.UploadAsync(new MemoryStream());
    }

    byte[] buffer = new byte[chunk[0].Length];
    await chunk[0].OpenReadStream().ReadAsync(buffer, 0, buffer.Length);

    var blockId = Guid.NewGuid().ToString();
    var blockIdBytes = Encoding.UTF8.GetBytes(blockId);
    var base64BlockId = Convert.ToBase64String(blockIdBytes);

    await blockBlobClient.StageBlockAsync(base64BlockId, new MemoryStream(buffer));
    var blockList = await blockBlobClient.GetBlockListAsync(BlockListTypes.All);
    var totalBlockCount = blockList.Value.CommittedBlocks.Count() + blockList.Value.UncommittedBlocks.Count();  // This line just returned 14 blocks
    await blockBlobClient.CommitBlockListAsync(blockList.Value.UncommittedBlocks.Select(block => block. Name).ToList());
}
c# .net asp.net-mvc azure
1个回答
0
投票

我已将以下代码添加到 Program.cs 中,并将超过 130 MB 的文件块上传到 Azure Blob 存储。

builder.Services.Configure<KestrelServerOptions>(options =>
        {
            options.Limits.MaxRequestBodySize = 500 * 1024 * 1024;
            options.Limits.MaxRequestBufferSize = 500 * 1024 * 1024;
        });

        builder.Services.Configure<FormOptions>(options =>
        {
            options.ValueLengthLimit = 500 * 1024 * 1024;
            options.MultipartBodyLengthLimit = 500 * 1024 * 1024;
        });

程序.cs:

var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddControllers();
        builder.Services.Configure<KestrelServerOptions>(options =>
        {
            options.Limits.MaxRequestBodySize = 500 * 1024 * 1024;
            options.Limits.MaxRequestBufferSize = 500 * 1024 * 1024;
        });

        builder.Services.Configure<FormOptions>(options =>
        {
            options.ValueLengthLimit = 500 * 1024 * 1024;
            options.MultipartBodyLengthLimit = 500 * 1024 * 1024;
        });

        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();
        var app = builder.Build();
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }
        app.UseHttpsRedirection();
        app.UseAuthorization();
        app.MapControllers();
        app.Run();

BlobController.cs:

using System.Text;
using Microsoft.AspNetCore.Mvc;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Specialized;
using Azure.Storage.Blobs.Models;

[ApiController]
[Route("api/[controller]")]
public class BlobController : ControllerBase
{
    private readonly BlobServiceClient blobServiceClient;
    private readonly string containerName = "<container_name>";

    public BlobController()
    {
        var connectionString = "<connec_string>";
        blobServiceClient = new BlobServiceClient(connectionString);
    }

    [HttpPost("{fileName}")]
    public async Task<IActionResult> UploadChunk(string fileName, List<IFormFile> chunks)
    {
        try
        {
            if (chunks.Count == 0)
            {
                return BadRequest("No file received from the request");
            }

            if (chunks.Count > 1)
            {
                return BadRequest("The request contains more than one file can be uploaded at a time");
            }

            var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
            var blockBlobClient = blobContainerClient.GetBlockBlobClient(fileName);

            if (!await blockBlobClient.ExistsAsync())
            {
                await blockBlobClient.UploadAsync(new MemoryStream());
            }

            var chunk = chunks[0];
            var blockId = Guid.NewGuid().ToString();
            var blockIdBytes = Encoding.UTF8.GetBytes(blockId);
            var base64BlockId = Convert.ToBase64String(blockIdBytes);

            byte[] buffer = new byte[chunk.Length];
            await chunk.OpenReadStream().ReadAsync(buffer, 0, buffer.Length);

            await blockBlobClient.StageBlockAsync(base64BlockId, new MemoryStream(buffer));

            var blockList = await blockBlobClient.GetBlockListAsync(BlockListTypes.All);
            var uncommittedBlocks = blockList.Value.UncommittedBlocks.ToList();
            uncommittedBlocks.Sort((b1, b2) => string.CompareOrdinal(b1.Name, b2.Name));

            await blockBlobClient.CommitBlockListAsync(uncommittedBlocks.Select(block => block.Name).ToList());

            return Ok();
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Internal server error: {ex.Message}");
        }
    }
}

输出:

进程成功运行如下:

enter image description here

我将文件块上传到 Azure Blob 存储,如下所示。

注意: 确保您有稳定的互联网连接。

enter image description here enter image description here enter image description here

Azure 门户:

我将 130 MB 及更大的文件上传到 Azure Blob 存储,如下所示。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.