Загрузка потока ответов в хранилище больших двоичных объектов

#c# #.net-core #httpclient #azure-blob-storage

#c# #.net-ядро #httpclient #azure-blob-storage

Вопрос:

к сожалению, я в значительной степени застрял в следующем сценарии:

Я использую .NET Core 3.1 и извлекаю данные через DI с помощью HttpClient (типизированный клиент) из URL. Эти данные представляют собой CSV-файл, который должен быть загружен в хранилище больших двоичных объектов Azure. В тот момент, когда я пытаюсь загрузить его в хранилище больших двоичных объектов, похоже, происходит сбой со следующим исключением:

  System.Net.Http: The operation was canceled. System.Net.Http: Error while copying content to a stream. 
 System.Net.Sockets: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request.. 
 The I/O operation has been aborted because of either a thread exit or an application request.
  

В настоящее время я понятия не имею, почему загрузка не работает. Другие загрузки из других потоков, похоже, работают без каких-либо ошибок. У кого-нибудь из вас есть подсказка для меня?

Мои классы

 public class Web<T> where T : BlobStorageContext
{

    private HttpClient _client { get; }
    private ILogger<Web> _logger;
    private Csv<T> _csv { get; }

    public Web(HttpClient client, Csv<T> csv, ILogger<Web> logger)
    {
        _client = client;
        _logger = logger;

        _csv = csv;
    }

    public async Task AccessWebFileAndSaveToAzureAsync()
    {
        ...

        var request = new HttpRequestMessage(HttpMethod.Get,
            url);
        
        using (var response = await _client.SendAsync(request))
        {
           
            await using (var str = await response.Content.ReadAsStreamAsync())
            {
                await _csv.WriteFileToAzureAsync(str);
            }
        }
    }
}


public class Csv<T> where T : BlobStorageContext
{
    private BlobServiceClient _blobServiceClient { get; set; }
    private ILogger<Csv<T>> _logger { get; set; }

    public Csv(IOptions<BlobStorageConfiguration<T>> configuration, ILogger<Csv<T>> logger)
    {
        _blobServiceClient = new BlobServiceClient(configuration.Value.ConnectionString());
        _logger = logger;
    }

    public async Task WriteFileToAzureAsync(Stream str)
    {
      
        var container = _blobServiceClient.GetBlobContainerClient("container);
        var blob = container.GetBlobClient(blobPath);
        await blob.UploadAsync(str, true);
    }
}
  

Комментарии:

1. Я предполагаю, что происходит то, что при загрузке в Azure исходный HTTP-запрос к вашему приложению остается открытым, и после определенного тайм-аута, ASP.NET Ядро завершает выполнение запроса от клиента. Вы пробовали использовать, например, Fiddler, чтобы посмотреть, что происходит?

2. Получаете ли вы исключение для большого двоичного объекта. Загружаемая строка синхронизации? Вы получаете это немедленно?

3. Не использовал никаких дополнительных инструментов @CodeCaster считаете ли вы, что для получения потока ответов в мое хранилище больших двоичных объектов необходим другой подход? должен ли я временно сохранять его в другом месте, а затем обрабатывать? проходит время, около нескольких минут, пока не возникает это исключение. Магнус

Ответ №1:

Скопируйте строку подключения и присвоите переменной storageAccount_connectionString в методе upload_ToBlob()

 storageAccount_connectionString = "your Azure storage account connection string"  
  

Следующие инструкции используются для создания объектов для учетной записи хранилища, клиента больших двоичных объектов и контейнера больших двоичных объектов.

 CloudStorageAccount mycloudStorageAccount = CloudStorageAccount.Parse(storageAccount_connectionString);  
CloudBlobClient blobClient = mycloudStorageAccount.CreateCloudBlobClient(); 
CloudBlobContainer container = blobClient.GetContainerReference(azure_ContainerName);   
  

Этот код предназначен для проверки, существует ли указанный контейнер в учетной записи хранилища или нет.

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

 if (container.CreateIfNotExists())
{      
    container.SetPermissionsAsync(new    
    BlobContainerPermissions    
   {    
       PublicAccess =BlobContainerPublicAccessType.Blob    
   });
} 
  

И следующий оператор используется для создания блочного объекта blob, используя имя файла с расширением

 CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(filename_withExtension);  
  

CloudBlockBlob.Для загрузки файла в хранилище больших двоичных объектов используется инструкция UploadFromStreamAsync (file).

Комментарии:

1. Я следовал этому руководству раньше ( learn.microsoft.com/de-de/azure/storage/blobs / … ) и это сработало без каких-либо проблем. Я думаю, что с самим подключением к хранилищу больших двоичных объектов проблем нет (поскольку я протестировал его с помощью простой строки и тестового файла без проблем).