Wywoływanie internetowego interfejsu API z platformy ASP.NET Core Blazor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

W tym artykule opisano sposób wywoływania internetowego interfejsu Blazor API z aplikacji.

Pakiet

Pakiet System.Net.Http.Json udostępnia metody rozszerzeń dla System.Net.Http.HttpClient programu i System.Net.Http.HttpContent które wykonują automatyczną serializacji i deserializacji przy użyciu polecenia System.Text.Json. Pakiet System.Net.Http.Json jest dostarczany przez udostępnioną platformę .NET i nie wymaga dodania odwołania do pakietu do aplikacji.

Przykładowe aplikacje

Zobacz przykładowe aplikacje w dotnet/blazor-samples repozytorium GitHub.

BlazorWebAppCallWebApi

Wywołaj zewnętrzny (nie w Blazor aplikacji internetowej) interfejs API listy zadań do wykonania z Blazor aplikacji internetowej:

  • Backend: aplikacja internetowego interfejsu API do obsługi listy zadań do wykonania na podstawie minimalnych interfejsów API. Aplikacja internetowego interfejsu Blazor API to oddzielna aplikacja od aplikacji internetowej, która może być hostowana na innym serwerze.
  • BlazorApp/BlazorApp.ClientBlazor: Aplikacja internetowa, która wywołuje aplikację internetowego interfejsu API z operacjami HttpClient listy zadań do wykonania, takimi jak tworzenie, odczytywanie, aktualizowanie i usuwanie elementów (CRUD) z listy zadań do wykonania.

W przypadku renderowania po stronie klienta (CSR), który obejmuje składniki interaktywnego zestawu WebAssembly i składniki automatyczne, które przyjęły csr, wywołania są wykonywane ze wstępnie skonfigurowanym plikiem HttpClient projektu klienta (BlazorApp.Client):Program

builder.Services.AddScoped(sp =>
    new HttpClient
    {
        BaseAddress = new Uri(builder.Configuration["FrontendUrl"] ?? "https://localhost:5002")
    });

W przypadku renderowania po stronie serwera (SSR), który obejmuje składniki wstępnie obsługiwane i interakcyjne składniki serwera, wstępnie obsługiwane składniki zestawu WebAssembly i składniki automatyczne, które są wstępnie obsługiwane lub mają wdrożony protokół SSR, wywołania są wykonywane przy użyciu zarejestrowanego HttpClient w Program pliku projektu serwera (BlazorApp):

builder.Services.AddHttpClient();

Wywołaj wewnętrzny (wewnątrz Blazor aplikacji internetowej) interfejs API listy filmów, w którym interfejs API znajduje się w projekcie Blazor serwera aplikacji internetowej:

  • BlazorAppBlazor: Aplikacja internetowa, która utrzymuje listę filmów:
    • Gdy operacje są wykonywane na liście filmów w aplikacji na serwerze, używane są zwykłe wywołania interfejsu API.
    • Gdy wywołania interfejsu API są wykonywane przez klienta internetowego, internetowy interfejs API jest używany do operacji listy filmów na podstawie minimalnych interfejsów API.
  • BlazorApp.Client: projekt Blazor klienta aplikacji internetowej zawierający interaktywne składniki WebAssembly i Auto do zarządzania listą filmów przez użytkownika.

W przypadku żądania CSR, w tym składników Interactive WebAssembly i składników automatycznych, które przyjęły żądania CSR, wywołania interfejsu API są wykonywane za pośrednictwem usługi opartej na kliencie (ClientMovieService), która używa wstępnie skonfigurowanej HttpClient konfiguracji w Program pliku projektu klienta (BlazorApp.Client). Ponieważ te wywołania są wykonywane za pośrednictwem publicznej lub prywatnej sieci Web, interfejs API listy filmów jest internetowym interfejsem API.

Poniższy przykład uzyskuje listę filmów z punktu końcowego /movies :

public class ClientMovieService(HttpClient http) : IMovieService
{
    public async Task<Movie[]> GetMoviesAsync(bool watchedMovies)
    {
        return await http.GetFromJsonAsync<Movie[]>("movies") ?? [];
    }
}

W przypadku usługi SSR, która obejmuje składniki wstępnie obsługiwane i interakcyjne składniki serwera, wstępnie obsługiwane składniki zestawu WebAssembly oraz składniki automatyczne, które są wstępnie obsługiwane lub zostały przyjęte przez usługę SSR, są wykonywane bezpośrednio za pośrednictwem usługi opartej na serwerze (ServerMovieService). Interfejs API nie opiera się na sieci, więc jest to standardowy interfejs API dla operacji CRUD listy filmów.

Poniższy przykład uzyskuje listę filmów:

public class ServerMovieService(MovieContext db) : IMovieService
{
    public async Task<Movie[]> GetMoviesAsync(bool watchedMovies)
    {
        return watchedMovies ? 
            await db.Movies.Where(t => t.IsWatched).ToArrayAsync() : 
            await db.Movies.ToArrayAsync();
    }
}

BlazorWebAppCallWebApi_Weather

Przykładowa aplikacja danych pogodowych, która używa renderowania strumieniowego na potrzeby danych pogodowych.

BlazorWebAssemblyCallWebApi

Wywołuje internetowy interfejs API listy zadań do wykonania z Blazor WebAssembly aplikacji:

  • Backend: aplikacja internetowego interfejsu API do obsługi listy zadań do wykonania na podstawie minimalnych interfejsów API.
  • BlazorTodoBlazor WebAssembly: aplikacja, która wywołuje internetowy interfejs API ze wstępnie skonfigurowanym do HttpClient wykonania operacjami CRUD listy zadań do wykonania.

Scenariusze po stronie serwera do wywoływania zewnętrznych internetowych interfejsów API

Składniki oparte na serwerze nazywają zewnętrzne internetowe interfejsy API przy użyciu HttpClient wystąpień, zwykle tworzone przy użyciu programu IHttpClientFactory. Aby uzyskać wskazówki dotyczące aplikacji po stronie serwera, zobacz Make HTTP requests using IHttpClientFactory in ASP.NET Core (Wykonywanie żądań HTTP przy użyciu elementu IHttpClientFactory w usłudze ASP.NET Core).

Aplikacja po stronie serwera domyślnie nie zawiera HttpClient usługi. Podaj element HttpClient aplikacji przy użyciu infrastruktury fabrykiHttpClient.

W pliku Program:

builder.Services.AddHttpClient();

Poniższy Razor składnik wysyła żądanie do internetowego interfejsu API dla gałęzi usługi GitHub podobnych do przykładu Podstawowe użycie w artykule Tworzenie żądań HTTP przy użyciu elementu IHttpClientFactory w ASP.NET Core .

CallWebAPI.razor:

@page "/call-web-api"
@using System.Text.Json
@using System.Text.Json.Serialization
@inject IHttpClientFactory ClientFactory

<h1>Call web API from a Blazor Server Razor component</h1>

@if (getBranchesError || branches is null)
{
    <p>Unable to get branches from GitHub. Please try again later.</p>
}
else
{
    <ul>
        @foreach (var branch in branches)
        {
            <li>@branch.Name</li>
        }
    </ul>
}

@code {
    private IEnumerable<GitHubBranch>? branches = [];
    private bool getBranchesError;
    private bool shouldRender;

    protected override bool ShouldRender() => shouldRender;

    protected override async Task OnInitializedAsync()
    {
        var request = new HttpRequestMessage(HttpMethod.Get,
            "https://api.github.com/repos/dotnet/AspNetCore.Docs/branches");
        request.Headers.Add("Accept", "application/vnd.github.v3+json");
        request.Headers.Add("User-Agent", "HttpClientFactory-Sample");

        var client = ClientFactory.CreateClient();

        var response = await client.SendAsync(request);

        if (response.IsSuccessStatusCode)
        {
            using var responseStream = await response.Content.ReadAsStreamAsync();
            branches = await JsonSerializer.DeserializeAsync
                <IEnumerable<GitHubBranch>>(responseStream);
        }
        else
        {
            getBranchesError = true;
        }

        shouldRender = true;
    }

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

W poprzednim przykładzie dla języka C# 12 lub nowszego dla zmiennej jest tworzona pusta tablica branches ([]). W przypadku wcześniejszych wersji języka C#utwórz pustą tablicę (Array.Empty<GitHubBranch>()).

Aby zapoznać się z dodatkowym przykładem roboczym, zobacz przykład przekazywania plików po stronie serwera, który przekazuje pliki do internetowego kontrolera interfejsu API w artykule dotyczącym przekazywania plików ASP.NET CoreBlazor.

Abstrakcje usług dla wywołań internetowego interfejsu API

Ta sekcja dotyczy Blazor usługi Web Apps, które utrzymują internetowy interfejs API w projekcie serwera lub przekształcają wywołania internetowego interfejsu API do zewnętrznego internetowego interfejsu API.

W przypadku korzystania z interakcyjnych trybów renderowania WebAssembly i Auto składniki są domyślnie wstępnie obsługiwane. Składniki automatyczne są również początkowo renderowane interaktywnie z serwera, zanim Blazor pakiet zostanie pobrany do klienta, a środowisko uruchomieniowe po stronie klienta zostanie aktywowane. Oznacza to, że składniki korzystające z tych trybów renderowania powinny być zaprojektowane tak, aby działały pomyślnie zarówno z poziomu klienta, jak i serwera. Jeśli składnik musi wywołać interfejs API oparty na projekcie serwera lub przekształcić żądanie do zewnętrznego internetowego interfejsu API (takiego, który znajduje się poza Blazor aplikacją internetową) podczas uruchamiania na kliencie, zalecaną metodą jest abstrakcja wywołania interfejsu API za interfejsem usługi oraz zaimplementowanie wersji klienta i serwera usługi:

  • Wersja klienta wywołuje internetowy interfejs API ze wstępnie skonfigurowanym HttpClientelementem .
  • Wersja serwera może zwykle uzyskiwać bezpośredni dostęp do zasobów po stronie serwera. Wstrzykiwanie elementu HttpClient na serwerze, który wykonuje wywołania z powrotem do serwera, nie jest zalecane, ponieważ żądanie sieciowe jest zwykle niepotrzebne. Alternatywnie interfejs API może być zewnętrzny dla projektu serwera, ale abstrakcja usługi dla serwera jest wymagana do przekształcenia żądania w jakiś sposób, na przykład w celu dodania tokenu dostępu do żądania proxied.

W przypadku korzystania z trybu renderowania zestawu WebAssembly można również wyłączyć prerendering, więc składniki są renderowane tylko z poziomu klienta. Aby uzyskać więcej informacji, zobacz tryby renderowania ASP.NET CoreBlazor.

Przykłady (przykładowe aplikacje):

Blazor Zewnętrzne internetowe interfejsy API aplikacji internetowej

Ta sekcja dotyczy Blazor usługi Web Apps, która wywołuje internetowy interfejs API obsługiwany przez oddzielny (zewnętrzny) projekt, prawdopodobnie hostowany na innym serwerze.

Blazor Usługa Web Apps zwykle prerender składniki webAssembly po stronie klienta i składniki automatyczne są renderowane na serwerze podczas renderowania statycznego lub interaktywnego po stronie serwera (SSR). HttpClient usługi nie są domyślnie rejestrowane w Blazor głównym projekcie aplikacji internetowej. Jeśli aplikacja jest uruchamiana tylko HttpClient z usługami zarejestrowanymi w .Client projekcie, zgodnie z opisem w sekcji Dodawanie HttpClient usługi , wykonanie aplikacji powoduje wystąpienie błędu w czasie wykonywania:

InvalidOperationException: Nie można podać wartości właściwości "Http" w typie "... {COMPONENT}". Nie ma zarejestrowanej usługi typu "System.Net.Http.HttpClient".

Użyj jednej z następujących metod:

  • HttpClient Dodaj usługi do projektu serwera, aby udostępnić HttpClient je podczas SSR. Użyj następującej rejestracji usługi w pliku projektu Program serwera:

    builder.Services.AddHttpClient();
    

    Nie jest wymagane jawne odwołanie do pakietu, ponieważ HttpClient usługi są udostępniane przez platformę udostępnioną.

    Przykład: internetowy interfejs API listy zadań do wykonania w przykładowej BlazorWebAppCallWebApiaplikacji

  • Jeśli prerendering nie jest wymagany dla składnika WebAssembly, który wywołuje internetowy interfejs API, wyłącz prerendering, postępując zgodnie ze wskazówkami w trybach renderowania ASP.NET CoreBlazor. Jeśli zastosujesz to podejście, nie musisz dodawać HttpClient usług do głównego projektu Blazor aplikacji internetowej, ponieważ składnik nie będzie wstępnie uwzględniany na serwerze.

Aby uzyskać więcej informacji, zobacz Rozwiązywanie problemów z usługami po stronie klienta podczas prerenderingu.

Wstępnie wstępnie wyeksenderowane dane

W przypadku wstępnego renderowania składników dwa razy: najpierw statycznie, a następnie interaktywnie. Stan nie przepływa automatycznie ze składnika wstępnego do interakcyjnego. Jeśli składnik wykonuje operacje inicjowania asynchronicznego i renderuje inną zawartość dla różnych stanów podczas inicjowania, na przykład "Ładowanie..." wskaźnik postępu, gdy składnik jest renderowany dwukrotnie, może zostać wyświetlony migotanie.

Możesz rozwiązać ten problem, przepływając wstępnie podsunięty stan przy użyciu interfejsu API stanu składnika trwałego, który przedstawiono w przykładowych BlazorWebAppCallWebApi aplikacjach i BlazorWebAppCallWebApi_Weather. Gdy składnik jest renderowany interaktywnie, może renderować ten sam sposób przy użyciu tego samego stanu. Jednak interfejs API nie działa obecnie z ulepszoną nawigacją, którą można obejść, wyłączając ulepszoną nawigację po linkach do strony (data-enhanced-nav=false). Aby uzyskać więcej informacji, zobacz następujące zasoby:

HttpClient Dodawanie usługi

Wskazówki zawarte w tej sekcji dotyczą scenariuszy po stronie klienta.

Składniki po stronie klienta nazywają internetowe interfejsy API przy użyciu wstępnie skonfigurowanej HttpClient usługi, która koncentruje się na tworzeniu żądań z powrotem do serwera pochodzenia. Dodatkowe HttpClient konfiguracje usług dla innych internetowych interfejsów API można utworzyć w kodzie dewelopera. Żądania składają się przy użyciu BlazorJSpomocników ON lub .HttpRequestMessage Żądania mogą obejmować konfigurację opcji interfejsu API pobierania.

Przykłady konfiguracji w tej sekcji są przydatne tylko wtedy, gdy jeden internetowy interfejs API jest wywoływany dla pojedynczego HttpClient wystąpienia w aplikacji. Gdy aplikacja musi wywołać wiele internetowych interfejsów API, z których każdy ma własny adres podstawowy i konfigurację, możesz zastosować następujące podejścia, które zostały omówione w dalszej części tego artykułu:

  • Nazwany za pomocą HttpClientIHttpClientFactory: każdy internetowy interfejs API ma unikatową nazwę. Gdy kod aplikacji lub Razor składnik wywołuje internetowy interfejs API, używa nazwanego HttpClient wystąpienia do wywołania.
  • Typd: HttpClientkażdy internetowy interfejs API jest wpisany. Gdy kod aplikacji lub Razor składnik wywołuje internetowy interfejs API, używa wystąpienia wpisanego HttpClient do wywołania.

Program W pliku dodaj usługęHttpClient, jeśli nie jest jeszcze obecna z szablonu projektu użytego Blazor do utworzenia aplikacji:

builder.Services.AddScoped(sp => 
    new HttpClient
    {
        BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
    });

W poprzednim przykładzie ustawiono adres podstawowy (IWebAssemblyHostEnvironment.BaseAddress), który pobiera adres builder.HostEnvironment.BaseAddress podstawowy dla aplikacji i jest zwykle pobierany z <base> wartości tagu href na stronie hosta.

Najczęstsze przypadki użycia własnego adresu podstawowego klienta to:

  • Projekt klienta (.Client) aplikacji internetowej (.NET 8 lub nowszej Blazor ) wykonuje wywołania internetowego interfejsu API ze składników webAssembly lub kodu uruchamianego na kliencie w zestawie WebAssembly do interfejsów API w aplikacji serwera.
  • Projekt klienta (Client) hostowanej Blazor WebAssembly aplikacji wykonuje wywołania internetowego interfejsu API do projektu serwera (Server). Pamiętaj, że hostowany Blazor WebAssembly szablon projektu nie jest już dostępny na platformie .NET 8 lub nowszym. Jednak hostowane Blazor WebAssembly aplikacje pozostają obsługiwane dla platformy .NET 8.

Jeśli wywołujesz zewnętrzny internetowy interfejs API (nie w tej samej przestrzeni adresu URL co aplikacja kliencka), ustaw identyfikator URI na podstawowy adres internetowego interfejsu API. Poniższy przykład ustawia podstawowy adres internetowego interfejsu API na https://localhost:5001, gdzie jest uruchomiona oddzielna aplikacja internetowego interfejsu API i gotowa do odpowiadania na żądania z aplikacji klienckiej:

builder.Services.AddScoped(sp => 
    new HttpClient
    {
        BaseAddress = new Uri("https://localhost:5001")
    });

JSPomocnicy WŁ.

HttpClient jest dostępna jako wstępnie skonfigurowana usługa do tworzenia żądań z powrotem na serwerze pochodzenia.

HttpClient i JSpomocnicy ON (System.Net.Http.Json.HttpClientJsonExtensions) są również używane do wywoływania punktów końcowych internetowego interfejsu API innych firm. HttpClientjest implementowany przy użyciu interfejsu API pobierania przeglądarki i podlega ograniczeniom, w tym wymuszaniu zasad tego samego źródła, które zostały omówione w dalszej części tego artykułu w sekcji Współużytkowanie zasobów między źródłami (CORS).

Adres podstawowy klienta jest ustawiony na adres serwera źródłowego. HttpClient Wstrzykiwanie wystąpienia do składnika przy użyciu @inject dyrektywy :

@using System.Net.Http
@inject HttpClient Http

System.Net.Http.Json Użyj przestrzeni nazw, aby uzyskać dostęp do HttpClientJsonExtensionselementu , w tym GetFromJsonAsync, PutAsJsonAsynci PostAsJsonAsync:

@using System.Net.Http.Json

W poniższych sekcjach omówiono JSpomocników ON:

System.Net.Http Zawiera dodatkowe metody wysyłania żądań HTTP i odbierania odpowiedzi HTTP, na przykład w celu wysłania żądania DELETE. Aby uzyskać więcej informacji, zobacz sekcję DELETE i dodatkowe metody rozszerzenia.

GET from ON () (GET from JSON (GetFromJsonAsync)

GetFromJsonAsync wysyła żądanie HTTP GET i analizuje JStreść odpowiedzi ON w celu utworzenia obiektu.

W poniższym kodzie składnika element todoItems jest wyświetlany przez składnik . GetFromJsonAsync jest wywoływana po zakończeniu inicjowania składnika (OnInitializedAsync).

todoItems = await Http.GetFromJsonAsync<TodoItem[]>("todoitems");

POST jako JSON (PostAsJsonAsync)

PostAsJsonAsync wysyła żądanie POST do określonego identyfikatora URI zawierającego wartość serializowaną jako JSWŁĄCZONE w treści żądania.

W poniższym kodzie newItemName składnika jest dostarczany przez element powiązany składnika. Metoda AddItem jest wyzwalana przez wybranie <button> elementu.

await Http.PostAsJsonAsync("todoitems", addItem);

PostAsJsonAsync zwraca wartość HttpResponseMessage. Aby wykonać deserializowanie JSzawartości ON z komunikatu odpowiedzi, użyj ReadFromJsonAsync metody rozszerzenia. W poniższym przykładzie dane dotyczące pogody są odczytywane JSjako tablica:

var content = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ?? 
    Array.Empty<WeatherForecast>();

PUT as JSON (PutAsJsonAsync)

PutAsJsonAsync wysyła żądanie HTTP PUT z zawartością zakodowaną JSw formacie ON.

W poniższym kodzie editItem składnika wartości i NameIsCompleted są dostarczane przez powiązane elementy składnika. Element jest ustawiany, gdy element Id jest wybrany w innej części interfejsu użytkownika (nie pokazano) i EditItem jest wywoływany. Metoda SaveItem jest wyzwalana przez wybranie <button> elementu. Poniższy przykład nie pokazuje ładowania todoItems dla zwięzłości. Zobacz sekcję GET from JSON (GetFromJsonAsync), aby zapoznać się z przykładem ładowania elementów.

await Http.PutAsJsonAsync($"todoitems/{editItem.Id}", editItem);

PutAsJsonAsync zwraca wartość HttpResponseMessage. Aby wykonać deserializowanie JSzawartości ON z komunikatu odpowiedzi, użyj ReadFromJsonAsync metody rozszerzenia. W poniższym przykładzie dane dotyczące pogody są odczytywane JSjako tablica:

var content = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ?? 
    Array.Empty<WeatherForecast>();

PATCH as JSON (PatchAsJsonAsync)

PatchAsJsonAsync wysyła żądanie HTTP PATCH z zakodowaną zawartością JSw formacie ON.

Uwaga

Aby uzyskać więcej informacji, zobacz JsonPatch w ASP.NET Core web API.

W poniższym przykładzie PatchAsJsonAsync otrzymuje JSdokument ON PATCH jako ciąg zwykłego tekstu z cudzysłowami ucieczki:

await Http.PatchAsJsonAsync(
    $"todoitems/{id}", 
    "[{\"operationType\":2,\"path\":\"/IsComplete\",\"op\":\"replace\",\"value\":true}]");

PatchAsJsonAsync zwraca wartość HttpResponseMessage. Aby wykonać deserializowanie JSzawartości ON z komunikatu odpowiedzi, użyj ReadFromJsonAsync metody rozszerzenia. W poniższym przykładzie dane zadań do wykonania są odczytywane JSjako tablica. Pusta tablica jest tworzona, jeśli żadna z danych elementu nie jest zwracana przez metodę, więc content nie ma wartości null po wykonaniu instrukcji:

var response = await Http.PatchAsJsonAsync(...);
var content = await response.Content.ReadFromJsonAsync<TodoItem[]>() ??
    Array.Empty<TodoItem>();

Ułożone z wcięciem, odstępami i niewyobrażonymi cudzysłowami niekodowany dokument PATCH jest wyświetlany jako następujący JS:

[
  {
    "operationType": 2,
    "path": "/IsComplete",
    "op": "replace",
    "value": true
  }
]

Aby uprościć tworzenie dokumentów PATCH w aplikacjach wystawiających żądania PATCH, aplikacja może korzystać z obsługi programu .NET JSON PATCH, jak pokazano w poniższych wskazówkach.

Microsoft.AspNetCore.JsonPatch Zainstaluj pakiet NuGet i użyj funkcji interfejsu API pakietu, aby utworzyć JsonPatchDocument żądanie PATCH.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Dodaj @using dyrektywy dla System.Text.Jsonprzestrzeni nazw , System.Text.Json.Serializationi Microsoft.AspNetCore.JsonPatch na początku Razor składnika:

@using System.Text.Json
@using System.Text.Json.Serialization
@using Microsoft.AspNetCore.JsonPatch

Utwórz element JsonPatchDocument dla elementu TodoItem z IsComplete ustawioną wartością trueReplace przy użyciu metody :

var patchDocument = new JsonPatchDocument<TodoItem>()
    .Replace(p => p.IsComplete, true);

Przekaż operacje dokumentu (patchDocument.Operations) do wywołania PatchAsJsonAsync :

private async Task UpdateItem(long id)
{
    await Http.PatchAsJsonAsync(
        $"todoitems/{id}", 
        patchDocument.Operations, 
        new JsonSerializerOptions()
        {
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
        });
}

JsonSerializerOptions.DefaultIgnoreCondition parametr jest ustawiony na wartość , aby JsonIgnoreCondition.WhenWritingDefault zignorować właściwość tylko wtedy, gdy jest równa wartości domyślnej dla jej typu.

Dodaj JsonSerializerOptions.WriteIndented wartość ustawioną na true , jeśli chcesz przedstawić JSładunek ON w przyjemnym formacie na potrzeby wyświetlania. Zapisywanie wcięcia JSON nie ma wpływu na przetwarzanie żądań PATCH i nie jest zwykle wykonywane w aplikacjach produkcyjnych dla żądań internetowego interfejsu API.

Postępuj zgodnie ze wskazówkami w artykule JsonPatch w ASP.NET Core web API , aby dodać akcję kontrolera PATCH do internetowego interfejsu API. Alternatywnie przetwarzanie żądań PATCH można zaimplementować jako minimalny interfejs API , wykonując następujące kroki.

Dodaj odwołanie do Microsoft.AspNetCore.Mvc.NewtonsoftJson pakietu NuGet do aplikacji internetowego interfejsu API.

Uwaga

Nie ma potrzeby dodawania odwołania do pakietu do Microsoft.AspNetCore.JsonPatch aplikacji, ponieważ odwołanie do Microsoft.AspNetCore.Mvc.NewtonsoftJson pakietu automatycznie dodaje odwołanie do Microsoft.AspNetCore.JsonPatchpakietu.

Program W pliku dodaj dyrektywę @using dla Microsoft.AspNetCore.JsonPatch przestrzeni nazw:

using Microsoft.AspNetCore.JsonPatch;

Podaj punkt końcowy potokowi przetwarzania żądań internetowego interfejsu API:

app.MapPatch("/todoitems/{id}", async (long id, TodoContext db) =>
{
    if (await db.TodoItems.FindAsync(id) is TodoItem todo)
    {
        var patchDocument = 
            new JsonPatchDocument<TodoItem>().Replace(p => p.IsComplete, true);
        patchDocument.ApplyTo(todo);
        await db.SaveChangesAsync();

        return TypedResults.Ok(todo);
    }

    return TypedResults.NoContent();
});

Ostrzeżenie

Podobnie jak w przypadku innych przykładów w pliku JsonPatch w artykule ASP.NET Core web API , poprzedni interfejs API PATCH nie chroni internetowego interfejsu API przed nadmiernym publikowaniem ataków. Aby uzyskać więcej informacji, zobacz Samouczek: tworzenie internetowego interfejsu API przy użyciu platformy ASP.NET Core.

Aby uzyskać w pełni działające środowisko PATCH, zobacz przykładową BlazorWebAppCallWebApiaplikację.

DELETE (DeleteAsync) i dodatkowe metody rozszerzenia

System.Net.Http Zawiera dodatkowe metody rozszerzenia do wysyłania żądań HTTP i odbierania odpowiedzi HTTP. HttpClient.DeleteAsync służy do wysyłania żądania HTTP DELETE do internetowego interfejsu API.

W poniższym kodzie <button> składnika element wywołuje metodę DeleteItem . Element powiązany <input> dostarcza id element do usunięcia.

await Http.DeleteAsync($"todoitems/{id}");

Nazwane z HttpClientIHttpClientFactory

IHttpClientFactory obsługiwane są usługi i konfiguracja nazwanego HttpClient elementu .

Uwaga

Alternatywą dla używania nazwy HttpClient z obiektu IHttpClientFactory jest użycie wpisanego HttpClientelementu . Aby uzyskać więcej informacji, zobacz sekcję Typd HttpClient .

Microsoft.Extensions.Http Dodaj pakiet NuGet do aplikacji.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Program W pliku projektu klienta:

builder.Services.AddHttpClient("WebAPI", client => 
    client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

Jeśli nazwany klient ma być używany przez wstępnie obsługiwane składniki Blazor po stronie klienta aplikacji internetowej, poprzednia rejestracja usługi powinna być wyświetlana zarówno w projekcie serwera, jak i w projekcie .Client . Na serwerze builder.HostEnvironment.BaseAddress jest zastępowany podstawowym adresem internetowego interfejsu API, który został opisany poniżej.

Powyższy przykład po stronie klienta ustawia adres podstawowy na (IWebAssemblyHostEnvironment.BaseAddress), który pobiera adres builder.HostEnvironment.BaseAddress podstawowy dla aplikacji po stronie klienta i zazwyczaj pochodzi z <base> wartości tagu href na stronie hosta.

Najczęstsze przypadki użycia własnego adresu podstawowego klienta to:

  • Projekt klienta (.Client) Blazor aplikacji internetowej, która wykonuje wywołania internetowego interfejsu API z składników WebAssembly/Auto lub kodu uruchamianego na kliencie w zestawie WebAssembly do interfejsów API w aplikacji serwera pod tym samym adresem hosta.
  • Projekt klienta (Client) hostowanej Blazor WebAssembly aplikacji, która wykonuje wywołania internetowego interfejsu API do projektu serwera (Server).

Najczęściej używanym przypadkiem użycia własnego adresu podstawowego klienta jest projekt klienta (Client) hostowanej Blazor WebAssembly aplikacji, która wykonuje wywołania internetowego interfejsu API do projektu serwera (Server).

Jeśli wywołujesz zewnętrzny internetowy interfejs API (nie w tej samej przestrzeni adresów URL co aplikacja kliencka) lub konfigurujesz usługi w aplikacji po stronie serwera (na przykład w celu obsługi wstępnego przetwarzania składników po stronie klienta na serwerze), ustaw identyfikator URI na podstawowy adres internetowego interfejsu API. Poniższy przykład ustawia podstawowy adres internetowego interfejsu API na https://localhost:5001, gdzie jest uruchomiona oddzielna aplikacja internetowego interfejsu API i gotowa do odpowiadania na żądania z aplikacji klienckiej:

builder.Services.AddHttpClient("WebAPI", client => 
    client.BaseAddress = new Uri(https://localhost:5001));

W poniższym kodzie składnika:

  • IHttpClientFactory Wystąpienie klasy tworzy o nazwie HttpClient.
  • Nazwana HttpClient jest używana do wystawiania żądania GET dla JSdanych prognozy pogody ON z internetowego interfejsu API pod adresem /forecast.
@inject IHttpClientFactory ClientFactory

...

@code {
    private Forecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        var client = ClientFactory.CreateClient("WebAPI");

        forecasts = await client.GetFromJsonAsync<Forecast[]>("forecast") ?? [];
    }
}

Przykładowa BlazorWebAppCallWebApiaplikacja demonstruje wywoływanie internetowego interfejsu API o nazwie HttpClient w składniku CallTodoWebApiCsrNamedClient . Aby zapoznać się z dodatkowym pokazem roboczym w aplikacji klienckiej na podstawie wywoływania programu Microsoft Graph o nazwie HttpClient, zobacz Use Graph API with ASP.NET Core (Używanie interfejsu API programu Graph z platformą ASP.NET Core Blazor WebAssembly).

Aby zapoznać się z pokazem roboczym w aplikacji klienckiej opartej na wywołaniu programu Microsoft Graph o nazwie HttpClient, zobacz Use Graph API with ASP.NET Core (Używanie interfejsu API programu Graph z platformą ASP.NET Core Blazor WebAssembly).

Wpisane HttpClient

Typd HttpClient używa co najmniej jednego wystąpienia aplikacji HttpClient , domyślnego lub nazwanego, aby zwracać dane z co najmniej jednego internetowego punktu końcowego interfejsu API.

Uwaga

Alternatywą dla używania typu jest HttpClient użycie nazwy z HttpClient klasy IHttpClientFactory. Aby uzyskać więcej informacji, zobacz sekcję Nazwane HttpClient z IHttpClientFactory .

Microsoft.Extensions.Http Dodaj pakiet NuGet do aplikacji.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

W poniższym przykładzie żądanie GET dla JSdanych prognozy pogody ON z internetowego interfejsu API pod adresem /forecast.

ForecastHttpClient.cs:

using System.Net.Http.Json;

namespace BlazorSample.Client;

public class ForecastHttpClient(HttpClient http)
{
    public async Task<Forecast[]> GetForecastAsync()
    {
        return await http.GetFromJsonAsync<Forecast[]>("forecast") ?? [];
    }
}

Program W pliku projektu klienta:

builder.Services.AddHttpClient<ForecastHttpClient>(client => 
    client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

Jeśli typowany klient ma być używany przez wstępnie obsługiwane składniki Blazor po stronie klienta aplikacji internetowej, poprzednia rejestracja usługi powinna pojawić się zarówno w projekcie serwera, jak i w projekcie .Client . Na serwerze builder.HostEnvironment.BaseAddress jest zastępowany podstawowym adresem internetowego interfejsu API, który został opisany poniżej.

W poprzednim przykładzie ustawiono adres podstawowy (IWebAssemblyHostEnvironment.BaseAddress), który pobiera adres builder.HostEnvironment.BaseAddress podstawowy aplikacji po stronie klienta i zazwyczaj pochodzi z <base> wartości tagu href na stronie hosta.

Najczęstsze przypadki użycia własnego adresu podstawowego klienta to:

  • Projekt klienta (.Client) Blazor aplikacji internetowej, która wykonuje wywołania internetowego interfejsu API z składników WebAssembly/Auto lub kodu uruchamianego na kliencie w zestawie WebAssembly do interfejsów API w aplikacji serwera pod tym samym adresem hosta.
  • Projekt klienta (Client) hostowanej Blazor WebAssembly aplikacji, która wykonuje wywołania internetowego interfejsu API do projektu serwera (Server).

Najczęściej używanym przypadkiem użycia własnego adresu podstawowego klienta jest projekt klienta (Client) hostowanej Blazor WebAssembly aplikacji, która wykonuje wywołania internetowego interfejsu API do projektu serwera (Server).

Jeśli wywołujesz zewnętrzny internetowy interfejs API (nie w tej samej przestrzeni adresów URL co aplikacja kliencka) lub konfigurujesz usługi w aplikacji po stronie serwera (na przykład w celu obsługi wstępnego przetwarzania składników po stronie klienta na serwerze), ustaw identyfikator URI na podstawowy adres internetowego interfejsu API. Poniższy przykład ustawia podstawowy adres internetowego interfejsu API na https://localhost:5001, gdzie jest uruchomiona oddzielna aplikacja internetowego interfejsu API i gotowa do odpowiadania na żądania z aplikacji klienckiej:

builder.Services.AddHttpClient<ForecastHttpClient>(client => 
    client.BaseAddress = new Uri(https://localhost:5001));

Składniki iniekcji typizowanego HttpClient w celu wywołania internetowego interfejsu API.

W poniższym kodzie składnika:

  • Wystąpienie powyższego ForecastHttpClient jest wstrzykiwane, co powoduje utworzenie typu HttpClient.
  • Typd HttpClient służy do wystawiania żądania GET dla JSdanych prognozy pogody ON z internetowego interfejsu API.
@inject ForecastHttpClient Http

...

@code {
    private Forecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await Http.GetForecastAsync();
    }
}

Przykładowa BlazorWebAppCallWebApiaplikacja demonstruje wywoływanie internetowego interfejsu API z wpisanym HttpClient w jego CallTodoWebApiCsrTypedClient składniku. Należy pamiętać, że składnik przyjmuje i renderowanie po stronie klienta (CSR) (InteractiveWebAssembly tryb renderowania) z prerenderingiem, więc typowana rejestracja usługi klienta jest wyświetlana w Program pliku zarówno projektu serwera, jak i .Client projektu.

Wskazówki zawarte w tej sekcji dotyczą scenariuszy po stronie klienta, które opierają się na uwierzytelnianiu cookie.

W przypadku cookieuwierzytelniania opartego na uwierzytelnianiu, które jest uważane za bezpieczniejsze niż uwierzytelnianie tokenu elementu nośnego, cookie poświadczenia można wysyłać przy użyciu każdego żądania internetowego interfejsu API przez wywołanie AddHttpMessageHandlerDelegatingHandler metody przy użyciu wstępnie skonfigurowanego HttpClientelementu . Program obsługi konfiguruje SetBrowserRequestCredentials element za pomocą BrowserRequestCredentials.Includepolecenia , który zaleca przeglądarce wysyłanie poświadczeń z każdym żądaniem, takich jak cookienagłówki uwierzytelniania s lub HTTP, w tym dla żądań między źródłami.

CookieHandler.cs:

public class CookieHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
        request.Headers.Add("X-Requested-With", ["XMLHttpRequest"]);

        return base.SendAsync(request, cancellationToken);
    }
}

Plik CookieHandler jest zarejestrowany w pliku Program :

builder.Services.AddTransient<CookieHandler>();

Procedura obsługi komunikatów jest dodawana do wszystkich wstępnie skonfigurowanych elementów wymagających HttpClientcookie uwierzytelniania:

builder.Services.AddHttpClient(...)
    .AddHttpMessageHandler<CookieHandler>();

Podczas komponowania elementu HttpRequestMessageustaw bezpośrednio poświadczenia i nagłówek żądania przeglądarki:

var requestMessage = new HttpRequestMessage() { ... };

requestMessage.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
requestMessage.Headers.Add("X-Requested-With", ["XMLHttpRequest"]);

HttpClient i HttpRequestMessage za pomocą opcji żądania interfejsu API pobierania

Wskazówki zawarte w tej sekcji dotyczą scenariuszy po stronie klienta, które opierają się na uwierzytelnianiu tokenu elementu nośnego.

HttpClient (Dokumentacja interfejsu API) i HttpRequestMessage może służyć do dostosowywania żądań. Można na przykład określić metodę HTTP i nagłówki żądań. Poniższy składnik wysyła POST żądanie do internetowego punktu końcowego interfejsu API i wyświetla treść odpowiedzi.

TodoRequest.razor:

@page "/todo-request"
@using System.Net.Http.Headers
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject HttpClient Http
@inject IAccessTokenProvider TokenProvider

<h1>ToDo Request</h1>

<h1>ToDo Request Example</h1>

<button @onclick="PostRequest">Submit POST request</button>

<p>Response body returned by the server:</p>

<p>@responseBody</p>

@code {
    private string? responseBody;

    private async Task PostRequest()
    {
        var requestMessage = new HttpRequestMessage()
        {
            Method = new HttpMethod("POST"),
            RequestUri = new Uri("https://localhost:10000/todoitems"),
            Content =
                JsonContent.Create(new TodoItem
                {
                    Name = "My New Todo Item",
                    IsComplete = false
                })
        };

        var tokenResult = await TokenProvider.RequestAccessToken();

        if (tokenResult.TryGetToken(out var token))
        {
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("Bearer", token.Value);

            requestMessage.Content.Headers.TryAddWithoutValidation(
                "x-custom-header", "value");

            var response = await Http.SendAsync(requestMessage);
            var responseStatusCode = response.StatusCode;

            responseBody = await response.Content.ReadAsStringAsync();
        }
    }

    public class TodoItem
    {
        public long Id { get; set; }
        public string? Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

BlazorImplementacja po stronie klienta interfejsu API pobierania używa interfejsu API pobierania i konfiguruje podstawowe opcje interfejsu HttpClient API pobierania żądań za pomocą HttpRequestMessage metod rozszerzeń i WebAssemblyHttpRequestMessageExtensions. Ustaw dodatkowe opcje przy użyciu metody rozszerzenia ogólnego SetBrowserRequestOption . Blazor a bazowy interfejs API pobierania nie dodawaj ani nie modyfikuj nagłówków żądań. Aby uzyskać więcej informacji na temat sposobu, w jaki agenci użytkowników, tacy jak przeglądarki, wchodzą w interakcje z nagłówkami, zapoznaj się z zewnętrznymi zestawami dokumentacji agenta użytkownika i innymi zasobami internetowymi.

Odpowiedź HTTP jest zwykle buforowana, aby umożliwić obsługę synchronicznych odczytów w zawartości odpowiedzi. Aby włączyć obsługę przesyłania strumieniowego odpowiedzi, użyj SetBrowserResponseStreamingEnabled metody rozszerzenia w żądaniu.

Aby uwzględnić poświadczenia w żądaniu między źródłami, użyj SetBrowserRequestCredentials metody rozszerzenia:

requestMessage.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);

Aby uzyskać więcej informacji na temat opcji interfejsu API pobierania, zobacz dokumentację internetową usługi MDN: WindowOrWorkerGlobalScope.fetch(): Parameters.

Obsługa błędów

Obsługa błędów odpowiedzi internetowego interfejsu API w kodzie dewelopera, gdy wystąpią. Na przykład GetFromJsonAsync oczekuje odpowiedzi ON z internetowego interfejsu API z wartością Content-Typeapplication/jsonJS. Jeśli odpowiedź nie JSma formatu ON, walidacja zawartości zgłasza błąd NotSupportedException.

W poniższym przykładzie punkt końcowy identyfikatora URI dla żądania danych prognozy pogody jest błędnie napisany. Identyfikator URI powinien być wyświetlany WeatherForecast w wywołaniu jako WeatherForcast, który nie ma litery w Forecastelemecie e .

Wywołanie GetFromJsonAsync oczekuje JS, że funkcja ON zostanie zwrócona, ale internetowy interfejs API zwraca kod HTML dla nieobsługiwanego wyjątku z wartością Content-Typetext/html. Nieobsługiwany wyjątek występuje, ponieważ ścieżka do /WeatherForcast nie została znaleziona, a oprogramowanie pośredniczące nie może obsłużyć strony ani widoku dla żądania.

Na OnInitializedAsync kliencie jest zgłaszany, NotSupportedException gdy zawartość odpowiedzi jest weryfikowana jako niewłJS. Wyjątek jest przechwytywane w catch bloku, gdzie logika niestandardowa może rejestrować błąd lub przedstawiać użytkownikowi przyjazny komunikat o błędzie.

ReturnHTMLOnException.razor:

@page "/return-html-on-exception"
@using {PROJECT NAME}.Shared
@inject HttpClient Http

<h1>Fetch data but receive HTML on unhandled exception</h1>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <h2>Temperatures by Date</h2>

    <ul>
        @foreach (var forecast in forecasts)
        {
            <li>
                @forecast.Date.ToShortDateString():
                @forecast.TemperatureC &#8451;
                @forecast.TemperatureF &#8457;
            </li>
        }
    </ul>
}

<p>
    @exceptionMessage
</p>

@code {
    private WeatherForecast[]? forecasts;
    private string? exceptionMessage;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            // The URI endpoint "WeatherForecast" is misspelled on purpose on the 
            // next line. See the preceding text for more information.
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForcast");
        }
        catch (NotSupportedException exception)
        {
            exceptionMessage = exception.Message;
        }
    }
}

Uwaga

Powyższy przykład służy do celów demonstracyjnych. Internetowy interfejs API można skonfigurować tak, aby zwracał wartość JSWŁĄCZONE nawet wtedy, gdy punkt końcowy nie istnieje lub na serwerze występuje nieobsługiwany wyjątek.

Aby uzyskać więcej informacji, zobacz Handle errors in ASP.NET Core apps (Obsługa błędów w aplikacjach platformy ASP.NET CoreBlazor).

Udostępnianie zasobów z różnych źródeł (CORS)

Zabezpieczenia przeglądarki ograniczają stronę internetową do wykonywania żądań do innej domeny niż ta, która obsłużyła stronę internetową. To ograniczenie określa się jako zasadę tego samego źródła. Zasady tego samego źródła ograniczają (ale nie uniemożliwiają) złośliwej witryny odczytywanie poufnych danych z innej witryny. Aby wysyłać żądania z przeglądarki do punktu końcowego z innym źródłem, punkt końcowy musi włączyć współużytkowanie zasobów między źródłami (CORS).

Aby uzyskać więcej informacji na temat mechanizmu CORS po stronie serwera, zobacz Włączanie żądań między źródłami (CORS) w ASP.NET Core. Przykłady artykułu nie dotyczą bezpośrednio Razor scenariuszy składników, ale artykuł jest przydatny do uczenia się ogólnych pojęć dotyczących mechanizmu CORS.

Aby uzyskać informacje na temat żądań CORS po stronie klienta, zobacz ASP.NET Core Blazor WebAssembly dodatkowe scenariusze zabezpieczeń.

Obsługa ochrony przed fałszerzami

Aby dodać obsługę ochrony przed fałszerzami do żądania HTTP, należy wstrzyknąć AntiforgeryStateProvider element i dodać element RequestToken do kolekcji nagłówków jako :RequestVerificationToken

@inject AntiforgeryStateProvider Antiforgery
private async Task OnSubmit()
{
    var antiforgery = Antiforgery.GetAntiforgeryToken();
    var request = new HttpRequestMessage(HttpMethod.Post, "action");
    request.Headers.Add("RequestVerificationToken", antiforgery.RequestToken);
    var response = await client.SendAsync(request);
    ...
}

Aby uzyskać więcej informacji, zobacz ASP.NET Core authentication and authorization (Uwierzytelnianie i autoryzacja na platformie ASP.NET CoreBlazor).

Blazor przykłady składników platformy do testowania dostępu do internetowego interfejsu API

Różne narzędzia sieciowe są publicznie dostępne do testowania internetowych aplikacji zaplecza interfejsu API, takich jak Firefox Browser Developer. Blazor Źródło referencyjne platformy zawiera HttpClient zasoby testowe, które są przydatne do testowania:

HttpClientTest Zasoby w dotnet/aspnetcore repozytorium GitHub

Uwaga

Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Dodatkowe zasoby

Ogólne

Po stronie serwera

Po stronie klienta