Файл, загруженный в Azure Storage Blob, показывает размер 0 байт

Я использую компонент Syncfusion Blazor Uploader, подробно описанный [здесь] (https://blazor.syncfusion.com/documentation/file-upload/getting-started#without-server-side-api-endpoint), чтобы загрузить файл. в хранилище BLOB-объектов Azure. Компонент находится в клиентском проекте и вызывает службу для маршрутизации вызова на контроллер, который находится в серверном проекте. Вот код, когда пользователь добавляет новый файл (на стороне клиента)

private async Task OnChange(UploadChangeEventArgs args)
{
    foreach (var file in args.Files)
    {
        try
        {
            var serializedFile = JsonSerializer.Serialize<Syncfusion.Blazor.Inputs.FileInfo>(file.FileInfo);
            
            await RemoteService.UploadStudyGuide(serializedFile);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

В настоящее время у меня есть требования — отправить его через службу, которая, в свою очередь, вызывает контроллер. Вот метод внутри сервиса

public async Task UploadStudyGuide(string serializedFile)
{    
    var response =
    await _httpClient.PostAsJsonAsync("StudyGuide/Upload", serializedFile);
}

а вот контроллер:

[HttpPost("Upload")]
public async Task Upload([FromBody] string serializedFile)
{
    string devConnectionString = "myConnectionString";
    string blobContainerName = "myContainerName";
    var file = JsonSerializer.Deserialize<Syncfusion.Blazor.Inputs.FileInfo>(serializedFile);

    try
    {
        // Azure connection string and container name passed as argument to get the Blob reference of container.
        // Provide your container name as second argument to this method. Example, upload-container.
        var container = new BlobContainerClient(devConnectionString, blobContainerName);

        // Method to create our container if it doesn’t exist.
        var createResponse = await container.CreateIfNotExistsAsync();

        // If successfully created our container then set a public access type to Blob.
        if (createResponse != null && createResponse.GetRawResponse().Status == 201)
            await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);

        // Method to create a new Blob client.
        var blob = container.GetBlobClient($"/ASPTDEV/StudyGuides/{file.Name}");


        // If the blob with the same name exists, then we delete the blob and its snapshots.
        await blob.DeleteIfExistsAsync(Azure.Storage.Blobs.Models.DeleteSnapshotsOption.IncludeSnapshots);

        // Create a file stream and use the UploadSync method to upload the blob.
        using (var fileStream = new FileStream(blob.BlobContainerName, FileMode.Create))
        {
            await blob.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = $"{file.MimeContentType}" });
        fileStream.Close();
        }
    }
    catch (Exception e)
    {
        Response.Clear();
        Response.StatusCode = 204;
        Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File failed to upload";
        Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;
    }
}

Файл успешно загружается в большой двоичный объект без ошибок. Но когда это происходит, размер равен 0 байтам. Я пробовал с заголовками типов контента и без них, а также с несколькими разными файлами с одинаковым результатом.

Если это поможет, вот класс Syncfusion, который я сериализую:


public class FileInfo
{
    [JsonPropertyName("fileSource")]
    public string FileSource { get; set; }

    [JsonPropertyName("id")]
    public string Id { get; set; }

    [JsonPropertyName("input")]
    public DOM Input { get; set; }

    [JsonPropertyName("list")]
    public DOM List { get; set; }

    [JsonPropertyName("name")]
    public string Name { get; set; }

    [DefaultValue(null)]
    [JsonPropertyName("rawFile")]
    public object RawFile { get; set; }

    [JsonPropertyName("size")]
    public double Size { get; set; }

    [JsonPropertyName("status")]
    public string Status { get; set; }

    [JsonPropertyName("statusCode")]
    public string StatusCode { get; set; }

    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("mimeContentType")]
    public string MimeContentType { get; set; }

    [JsonPropertyName("lastModifiedDate")]
    public DateTime LastModifiedDate { get; set; }
 
    [JsonPropertyName("validationMessages")]
    public ValidationMessages ValidationMessages { get; set; }
}
Для развертывания Сайтов с использованием Blazor, Angular и React с репозиторием на GitHub на Cloudflare
Для развертывания Сайтов с использованием Blazor, Angular и React с репозиторием на GitHub на Cloudflare
Как развернуть сайты с помощью Blazor, Angular и React с репозиторием на GitHub на Cloudflare.
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина ошибки

Это код, который вызывает у вас проблему:

using (var fileStream = new FileStream(blob.BlobContainerName, FileMode.Create))
{
    await blob.UploadAsync(fileStream, // this is the problem.

Вы создаете новый (то есть совершенно пустой) FileStream. Затем вы просите клиент BLOB-объектов загрузить этот пустой объект fileStream. Итак, вы получаете пустой BLOB-объект. Нулевая длина.

Решение 1

Вы можете записать свои данные напрямую, используя BlobClient, вообще не нуждаясь в FileStream:

await blob.UploadAsync(BinaryData.FromString(serializedFile));

Решение 2

Из вашего примера неясно, как именно вы хотите хранить данные serializedFile в Blob, поэтому первое решение может быть не тем, что вам нужно.

Например, если вам нужно сериализовать объект FileInfo, вы можете использовать поток. Но вместо того, чтобы создавать пустой FileStream и писать его, вы можете попросить BlobClient открыть поток, а затем написать в него из JsonSerializer:

using (var stream = await blob.OpenWriteAsync(true))
{
    await JsonSerializer.SerializeAsync(stream, file);
}

Вы совершенно правы. Спасибо, это исправлено.

Frawsty 16.08.2024 00:40

Рад, что это помогло!

Andrew B 16.08.2024 00:43

Другие вопросы по теме

Чтение информации из подкаталогов в BLOB-объекте Azure
Не удалось загрузить файл или сборку «System.Diagnostics.DiagnosticSource», версия = 6.0.0.0. Система не может найти указанный файл
Файлы в локальной общей папке Службы приложений Azure недоступны при использовании общедоступного URL-адреса
SchemaColumnConvertNotSupportedException: столбец: [Col_Name], физический тип: INT64, логический тип: строка
Невозможно прочитать большие двоичные объекты через BlobContainerClient для больших двоичных объектов с пустыми префиксами папок
Извлечение данных из хранилища BLOB-объектов в Databricks[автоматизация]
Рекомендуемая практика доступа к хранилищу BLOB-объектов
Как скачать файл в учетную запись хранения Azure из приложения-функции
Дополнительные файлы (блочные BLOB-объекты), создаваемые при копировании хранилища BLOB-объектов в ADF
Как скопировать все контейнеры без явного упоминания в массиве между двумя разными учетными записями хранения