Sdílet prostřednictvím


Kurz: Připojení aplikace ASP.NET Core k integraci úložiště .NET Aspire

Aplikace nativní pro cloud často vyžadují škálovatelná řešení úložiště, která poskytují možnosti, jako je úložiště objektů blob, fronty nebo částečně strukturované databáze NoSQL. integrace .NET Aspire zjednodušují připojení k různým službám úložiště, například Azure Blob Storage. V tomto kurzu vytvoříte aplikaci ASP.NET Core, která používá integrace .NET Aspire pro připojení k Azure Blob Storage a Azure Queue Storage k odesílání lístků podpory. Aplikace odešle lístky do fronty ke zpracování a nahraje přílohu do úložiště. Naučíte se:

  • Vytvořte základní aplikaci .NET, která je nastavená k použití integrací .NET Aspire.
  • Přidejte integrace .NET.NET Aspire pro připojení k více službám úložiště
  • Konfigurace a používání funkcí komponent .NET.NET Aspire k odesílání a příjmu dat

Požadavky

Pokud chcete pracovat s .NET.NET Aspire, potřebujete místně nainstalovat následující:

Další informace najdete v tématu .NET.NET Aspire nastavení a nástrojea .NET.NET Aspire SDK.

Prozkoumání dokončené ukázkové aplikace

Dokončená verze ukázkové aplikace z tohoto kurzu je k dispozici na GitHub. Projekt je také strukturovaný jako šablona pro Azure Developer CLI, což znamená, že můžete pomocí příkazu azd up automatizovat zřizování Azure prostředků, pokud máte nástroj nainstalovaný.

git clone https://github.com/Azure-Samples/dotnet-aspire-connect-storage.git

Nastavte prostředky úložiště Azure

V tomto článku budete potřebovat přístup přispěvatele dat k účtu Azure Storage s kontejnerem objektů blob a frontou úložiště. Ujistěte se, že máte k dispozici následující prostředky a konfigurace:

V tomto článku budete muset vytvořit kontejner objektů blob a prostředek fronty úložiště v místním vývojovém prostředí pomocí emulátoru. K tomu použijte Azurite. Azurite je bezplatný opensourcový multiplatformní Azure rozhraní API úložiště kompatibilní server (emulátor), který běží v kontejneru Docker.

Pokud chcete použít emulátor, musíte nainstalovatAzurite .

  1. Účet úložiště Azure – Vytvoření účtu úložiště.
  2. Kontejner úložiště objektů blob s názvem fileuploads - Vytvořit kontejner úložiště objektů blob.
  3. Fronta úložiště s názvem tickets - Vytvořit frontu úložiště.

Spuštěním následujících příkazů v Azure CLI nebo CloudShellu nastavte požadované prostředky Azure Storage:

az group create --name aspirestorage --location eastus2
az storage account create -n aspirestorage -g aspirestorage -l eastus2
az storage container create -n fileuploads --account-name aspirestorage
az storage queue create -n tickets --account-name aspirestorage

Musíte také přiřadit následující role k uživatelskému účtu, ke kterému jste přihlášeni Visual Studio:

Azure Developer CLI umožňuje zřizovat a nasazovat Azure prostředky pomocí systému šablon. Tento tutoriál poskytuje kompletní šablonu, která zřídí požadované Azure prostředky a obsahuje úplný ukázkový kód aplikace. Spuštěním následujících příkazů inicializujete a spustíte šablonu:

  1. Spuštěním azd auth login se přihlaste k Azure:

    azd auth login
    
  2. Spuštěním azd init naklonujte a inicializujete ukázkovou šablonu:

    azd init --template dotnet-aspire-connect-storage
    
  3. Spusťte azd up k zajištění prostředků Azure:

    azd up
    
  4. Po zobrazení výzvy vyberte předplatné a oblast Azure pro přidělené prostředky. Šablona se spustí a dokončí následující úlohy:

    • Vytvoří účet úložiště Azure s povolenými službami blob a front.
    • Vytvoří kontejner úložiště objektů blob s názvem fileUploads
    • Vytvoří frontu s názvem tickets
    • Přiřadí uživatelskému účtu, který spustil šablonu, následující role.
      • Přispěvatel dat služby Storage Blob
      • Přispěvatel dat fronty služby Storage

Po úspěšném dokončení operace máte dvě možnosti:

  • Možnost 1: Spusťte ukázkovou aplikaci .NET v adresáři šablony src a experimentujte s dokončenou aplikací.
  • Možnost 2: Krok za krokem sestavte ukázkovou aplikaci pomocí sekcí uvedených dále a připojte ji k prostředkům Azure zřízeným azd.

Vytvoření ukázkového řešení

Vytvořte projekt .NET Aspire pomocí Visual Studio nebo rozhraní příkazového řádku .NET.

  1. V horní části Visual Studiopřejděte na File>New>Project.
  2. V dialogovém okně vyhledejte Aspire a vyberte .NET.NET Aspire Úvodní aplikace. Zvolte Další.
  3. Na obrazovce Konfigurujte svůj nový projekt:
    • Zadejte název řešení AspireStorage a vyberte Další.
  4. Na obrazovce Další informace:
    • Zrušte zaškrtnutí Použít Redis pro ukládání do mezipaměti (pro účely tohoto kurzu se nevyžaduje).
    • Vyberte Vytvořit.

Visual Studio vytvoří nové ASP.NET Core řešení strukturované pro použití .NET Aspire.

Řešení se skládá z následujících projektů:

  • AspireStorage.ApiService – projekt rozhraní API s výchozími konfiguracemi služby .NET.NET Aspire.
  • AspireStorage.AppHost – projekt orchestrátoru navržený pro připojení a konfiguraci různých projektů a služeb vaší aplikace. Orchestrátor by měl být nastaven jako spouštěcí projekt.
  • AspireStorage.ServiceDefaults – sdílená knihovna tříd pro uložení kódu, který se dá znovu použít napříč projekty ve vašem řešení.
  • AspireStorage.Web – projekt BlazorServer, který slouží jako front-end vaší aplikace.

Přidání projektu Worker Service

Dále přidejte do řešení projekt Worker Service pro načtení a zpracování zpráv, jakmile jsou přidány do fronty úložiště Azure.

  1. V Průzkumníku řešení klikněte pravým tlačítkem na horní uzel řešení AspireStorage a vyberte Přidat>Nový projekt.
  2. Vyhledejte a vyberte šablonu Worker Service a zvolte Další.
  3. Jako název projektu zadejte AspireStorage.WorkerService a vyberte Další.
  4. Na obrazovce Další informace:
    • Ujistěte se, že je vybraná .NET 9.0.
    • Ujistěte se, že je zaškrtnuté políčko Zapsat se do .NET.NET Aspire orchestrace a zvolte Vytvořit.

Visual Studio přidá projekt do vašeho řešení a aktualizuje Program.cs soubor AspireStorage.AppHost projektu novým řádkem kódu:

builder.AddProject<Projects.AspireStorage_WorkerService>(
    "aspirestorage-workerservice");

Visual Studio nástroj přidal tento řádek kódu pro registraci nového projektu do objektu IDistributedApplicationBuilder, který umožňuje orchestrační funkce. Pro více informací viz téma .NET.NET Aspire orchestrace – přehled.

Hotová struktura řešení by měla vypadat přibližně takto:

snímek obrazovky znázorňující strukturu ukázkového řešení úložiště .NET.NET Aspire

Přidání integrací .NET Aspire do aplikace Blazor

Do projektu .NET Aspire přidejte .NET Aspire a Azure Queue Storage:

dotnet add package Aspire.Azure.Storage.Blobs
dotnet add package Aspire.Azure.Storage.Queues

Váš projekt AspireStorage.Web je teď nastavený tak, aby používal integrace .NET.NET Aspire. Tady je aktualizovaný soubor AspireStorage.Web.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\AspireStorage.ServiceDefaults\AspireStorage.ServiceDefaults.csproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Azure.Storage.Blobs" Version="9.0.0" />
    <PackageReference Include="Aspire.Azure.Storage.Queues" Version="9.0.0" />
  </ItemGroup>

</Project>

Dalším krokem je přidání integrací do aplikace.

V souboru Program.cs projektu AspireStorage.Web přidejte volání metod rozšíření AddAzureBlobClient a AddAzureQueueClient po vytvoření builder, ale před voláním na AddServiceDefaults. Další informace viz .NET.NET Aspire výchozí nastavení služby. Jako parametr zadejte název připojovacího řetězce.

using AspireStorage.Web;
using AspireStorage.Web.Components;

using Azure.Storage.Blobs;
using Azure.Storage.Queues;

var builder = WebApplication.CreateBuilder(args);

builder.AddAzureBlobClient("BlobConnection");
builder.AddAzureQueueClient("QueueConnection");

// Add service defaults & Aspire components.
builder.AddServiceDefaults();

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddOutputCache();

builder.Services.AddHttpClient<WeatherApiClient>(client =>
    {
        // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
        // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
        client.BaseAddress = new("https+http://apiservice");
    });

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
else
{
    // In development, create the blob container and queue if they don't exist.
    var blobService = app.Services.GetRequiredService<BlobServiceClient>();
    var docsContainer = blobService.GetBlobContainerClient("fileuploads");

    await docsContainer.CreateIfNotExistsAsync();

    var queueService = app.Services.GetRequiredService<QueueServiceClient>();
    var queueClient = queueService.GetQueueClient("tickets");

    await queueClient.CreateIfNotExistsAsync();
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

app.UseOutputCache();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.MapDefaultEndpoints();

app.Run();
using AspireStorage.Web;
using AspireStorage.Web.Components;

using Azure.Storage.Blobs;
using Azure.Storage.Queues;

var builder = WebApplication.CreateBuilder(args);

builder.AddAzureBlobClient("BlobConnection");
builder.AddAzureQueueClient("QueueConnection");

// Add service defaults & Aspire components.
builder.AddServiceDefaults();

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddOutputCache();

builder.Services.AddHttpClient<WeatherApiClient>(client =>
    {
        // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
        // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
        client.BaseAddress = new("https+http://apiservice");
    });

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

app.UseOutputCache();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.MapDefaultEndpoints();

app.Run();

S dalšími příkazy using tyto metody provádí následující úlohy:

Když se projekt AspireStorage.Web spustí, vytvoří se kontejner fileuploads ve službě Azurite Blob Storage a fronta tickets ve službě Azurite Queue Storage. Toto je podmíněné, když je aplikace spuštěná ve vývojovém prostředí. Když je aplikace spuštěná v produkčním prostředí, předpokládá se, že kontejner a fronta již byly vytvořeny.

Přidání integrace .NET Aspire do Worker Service

Pracovní služba zpracovává načítání zpráv z fronty Azure Storage ke zpracování. Do aplikace AspireStorage.WorkerService přidejte integrační balíček Queue Storage:

dotnet add package Aspire.Azure.Storage.Queues

V souboru Program.cs projektu AspireStorage.WorkerService přidejte volání metody rozšíření AddAzureQueueClient po vytvoření builder, ale před voláním AddServiceDefaults:

using AspireStorage.WorkerService;

var builder = Host.CreateApplicationBuilder(args);

builder.AddAzureQueueClient("QueueConnection");

builder.AddServiceDefaults();
builder.Services.AddHostedService<WorkerService>();

var host = builder.Build();
host.Run();

Tato metoda zpracovává následující úlohy:

  • Zaregistrujte QueueServiceClient v kontejneru DI pro připojení k Azure Storage Queues.
  • Automaticky povolte odpovídající kontroly stavu, protokolování a telemetrii pro příslušné služby.

Vytvoření formuláře

Aplikace vyžaduje formulář, aby uživatel mohl odeslat informace o podporovém lístku a nahrát přílohu. Aplikace nahraje připojený soubor na vlastnost Document (IFormFile) na Azure Blob Storage pomocí do-injektovaného BlobServiceClient. QueueServiceClient odešle zprávu obsahující Title a Description do Storage fronty Azure.

Pomocí následujícího kódu Razor vytvořte základní formulář a nahraďte obsah souboru Home.razor v adresáři AspireStorage.Web/Components/ Pages:

@page "/"

@using System.ComponentModel.DataAnnotations
@using Azure.Storage.Blobs
@using Azure.Storage.Queues

@inject BlobServiceClient BlobClient
@inject QueueServiceClient QueueServiceClient

<PageTitle>Home</PageTitle>

<div class="text-center">
    <h1 class="display-4">Request Support</h1>
</div>

<EditForm Model="@Ticket" FormName="Tickets" method="post"
          OnValidSubmit="@HandleValidSubmit" enctype="multipart/form-data">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div class="mb-4">
        <label>Issue Title</label>
        <InputText class="form-control" @bind-Value="@Ticket.Title" />
        <ValidationMessage For="() => Ticket.Title" />
    </div>
    <div class="mb-4">
        <label>Issue Description</label>
        <InputText class="form-control" @bind-Value="@Ticket.Description" />
        <ValidationMessage For="() => Ticket.Description" />
    </div>
    <div class="mb-4">
        <label>Attachment</label>
        <InputFile class="form-control" name="Ticket.Document" />
        <ValidationMessage For="() => Ticket.Document" />
    </div>
    <button class="btn btn-primary" type="submit">Submit</button>
    <button class="btn btn-danger mx-2" type="reset" @onclick=@ClearForm>Clear</button>
</EditForm>

@code {
    [SupplyParameterFromForm(FormName = "Tickets")]
    private SupportTicket Ticket { get; set; } = new();

    private async Task HandleValidSubmit()
    {
        var docsContainer = BlobClient.GetBlobContainerClient("fileuploads");

        // Upload file to blob storage
        await docsContainer.UploadBlobAsync(
            Ticket.Document.FileName,
            Ticket.Document.OpenReadStream());

        // Send message to queue
        var queueClient = QueueServiceClient.GetQueueClient("tickets");

        await queueClient.SendMessageAsync(
             $"{Ticket.Title} - {Ticket.Description}");

        ClearForm();
    }

    private void ClearForm() => Ticket = new();

    private class SupportTicket()
    {
        [Required] public string Title { get; set; } = default!;
        [Required] public string Description { get; set; } = default!;
        [Required] public IFormFile Document { get; set; } = default!;
    }
}

Pro více informací o vytváření formulářů v Blazor, viz ASP.NET CoreBlazor přehled formulářů.

Aktualizace apphostu

Projekt AspireStorage.AppHost je orchestrátorem vaší aplikace. Zodpovídá za připojení a konfiguraci různých projektů a služeb vaší aplikace. Orchestrátor by měl být nastaven jako spouštěcí projekt.

Pokud chcete do Azurepřidat podporu hostování úložiště IDistributedApplicationBuilder, nainstalujte balíček NuGet 📦Aspire.Hosting.Storage.Azure.

dotnet add package Aspire.Hosting.Azure.Storage

Obsah souboru Program.cs v projektu AspireStorage.App Host nahraďte následujícím kódem:

using Microsoft.Extensions.Hosting;

var builder = DistributedApplication.CreateBuilder(args);

var storage = builder.AddAzureStorage("Storage");

if (builder.Environment.IsDevelopment())
{
    storage.RunAsEmulator();
}

var blobs = storage.AddBlobs("BlobConnection");
var queues = storage.AddQueues("QueueConnection");

var apiService = builder.AddProject<Projects.AspireStorage_ApiService>("apiservice");

builder.AddProject<Projects.AspireStorage_Web>("webfrontend")
    .WithExternalHttpEndpoints()
    .WithReference(apiService)
    .WithReference(blobs)
    .WithReference(queues); 

builder.AddProject<Projects.AspireStorage_WorkerService>("aspirestorage-workerservice")
    .WithReference(queues);

builder.Build().Run();

Předchozí kód přidá Azure úložiště, objekty blob a fronty, a při vývojovém režimu používá emulátor. Každý projekt definuje odkazy na tyto zdroje, na nichž závisí.

using Microsoft.Extensions.Hosting;

var builder = DistributedApplication.CreateBuilder(args);

var storage = builder.AddAzureStorage("Storage");

var blobs = storage.AddBlobs("BlobConnection");
var queues = storage.AddQueues("QueueConnection");

var apiService = builder.AddProject<Projects.AspireStorage_ApiService>("apiservice");

builder.AddProject<Projects.AspireStorage_Web>("webfrontend")
    .WithExternalHttpEndpoints()
    .WithReference(apiService)
    .WithReference(blobs)
    .WithReference(queues); 

builder.AddProject<Projects.AspireStorage_WorkerService>("aspirestorage-workerservice")
    .WithReference(queues);

builder.Build().Run();

Předchozí kód přidá Azure úložiště, objekty blob a fronty a definuje odkazy na tyto prostředky v rámci každého projektu, který na nich závisí.

Zpracování položek ve frontě

Když se do fronty tickets umístí nová zpráva, měla by pracovní služba načíst, zpracovat a odstranit zprávu. Aktualizujte třídu Worker.cs a nahraďte obsah následujícím kódem:

using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace AspireStorage.WorkerService;

public sealed class WorkerService(
    QueueServiceClient client,
    ILogger<WorkerService> logger) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var queueClient = client.GetQueueClient("tickets");
        await queueClient.CreateIfNotExistsAsync(cancellationToken: stoppingToken);

        while (!stoppingToken.IsCancellationRequested)
        {
            QueueMessage[] messages =
                await queueClient.ReceiveMessagesAsync(
                    maxMessages: 25, cancellationToken: stoppingToken);

            foreach (var message in messages)
            {
                logger.LogInformation(
                    "Message from queue: {Message}", message.MessageText);

                await queueClient.DeleteMessageAsync(
                    message.MessageId,
                    message.PopReceipt,
                    cancellationToken: stoppingToken);
            }

            // TODO: Determine an appropriate time to wait 
            // before checking for more messages.
            await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
        }
    }
}

Než může služba pracovníka zpracovávat zprávy, musí být schopná se připojit k frontě Azure Storage. U Azurite je třeba zajistit, aby byla fronta dostupná ještě před tím, než pracovní služba začne provádět zpracování fronty zpráv.

using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace AspireStorage.WorkerService;

public sealed class WorkerService(
    QueueServiceClient client,
    ILogger<WorkerService> logger) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var queueClient = client.GetQueueClient("tickets");
        while (!stoppingToken.IsCancellationRequested)
        {
            QueueMessage[] messages =
                await queueClient.ReceiveMessagesAsync(
                    maxMessages: 25, cancellationToken: stoppingToken);

            foreach (var message in messages)
            {
                logger.LogInformation(
                    "Message from queue: {Message}", message.MessageText);

                await queueClient.DeleteMessageAsync(
                    message.MessageId,
                    message.PopReceipt,
                    cancellationToken: stoppingToken);
            }

            // TODO: Determine an appropriate time to wait 
            // before checking for more messages.
            await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
        }
    }
}

Pracovní služba zpracovává zprávy připojením k frontě Azure Storage a stahováním zpráv z fronty.

Pracovní služba zpracovává zprávy ve frontě a odstraní je po jejich zpracování.

Konfigurace připojovacích řetězců

Projekty AspireStorage a AspireStorage.Worker musí být nakonfigurované tak, aby se připojily ke správnému Azure účtu úložiště, který jste vytvořili dříve. Koncové body pro služby blob a fronty v účtu úložiště můžete zadat pomocí souboru appsettings.json v každém projektu.

  1. V projektu AspireStorage přidejte do souboru appsettings.Development.json následující konfiguraci:

      "ConnectionStrings": {
        "BlobConnection": "https://<your-storage-account-name>.blob.core.windows.net/",
        "QueueConnection": "https://<your-storage-account-name>.queue.core.windows.net/"
      }
    
  2. V projektu AspireStorage.Worker přidejte do souboru appsettings.Development.json následující konfiguraci:

      "ConnectionStrings": {
        "QueueConnection": "https://<your-storage-account-name>.queue.core.windows.net/"
      }
    

Místní spuštění a otestování aplikace

Ukázková aplikace je teď připravená k testování. Pomocí následujících kroků ověřte, že se odesílají odeslaná data formuláře do služby Azure Blob Storage a Azure Queue Storage:

  1. Stisknutím tlačítka Spustit v horní části Visual Studio spusťte řídicí panel projektu .NET Aspire v prohlížeči.

  2. Na stránce prostředků, v řádku aspirestorage.web, klikněte na odkaz ve sloupci Endpoints a otevřete uživatelské rozhraní vaší aplikace.

    snímek obrazovky zobrazující domovskou stránku podpůrné aplikace .NET.NET Aspire

  3. Zadejte ukázková data do polí formuláře Title a Description a vyberte jednoduchý soubor, který chcete nahrát.

  4. Vyberte tlačítko Odeslat a formulář odešle lístek podpory ke zpracování a vymaže tento formulář.

  5. Na samostatné kartě prohlížeče přejděte pomocí portálu do prohlížeče Storage ve vašem účtu úložiště .

  6. Vyberte Kontejnery a pak přejděte do kontejneru Documents a podívejte se na nahraný soubor.

  7. Zprávu ve frontě můžete ověřit tak, že se podíváte na protokoly projektu řídicího panelu a v rozevíracím seznamu vyberete aspirestorage.workerservice.

    snímek obrazovky zobrazující výstup konzoly aplikace Worker.

Shrnutí

Ukázková aplikace, kterou jste vytvořili, ukazuje ukládání datových bloků z webové aplikace ASP.NET CoreBlazor a zpracování front v .NET Worker Service. Vaše aplikace se připojí ke službě Azure Storage pomocí integrace .NET Aspire. Aplikace odešle lístky podpory do fronty ke zpracování a nahraje přílohu do úložiště.

Vzhledem k tomu, že se rozhodnete používat Azurite, nemusíte tyto prostředky po dokončení testování vyčistit, protože jste je vytvořili místně v kontextu emulátoru. Emulátor vám umožnil otestovat aplikaci místně bez jakýchkoli nákladů, protože se nezřídily ani nevytvořily žádné prostředky Azure.

Vyčištění prostředků

Spuštěním následujícího příkazu rozhraní příkazového řádku Azure odstraňte skupinu prostředků, pokud už nepotřebujete Azure prostředky, které jste vytvořili. Odstraněním skupiny prostředků se odstraní také prostředky obsažené v této skupině.

az group delete --name <your-resource-group-name>

Další informace najdete v tématu Vyčištění prostředků v Azure.