Laden...

Wie kann ich Daten von einer Blazor WebAssembly App von einer ASP.NET Core-Web-API abrufen (CORS)?

Erstellt von Jörg vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.514 Views
J
Jörg Themenstarter:in
152 Beiträge seit 2009
vor 3 Jahren
Wie kann ich Daten von einer Blazor WebAssembly App von einer ASP.NET Core-Web-API abrufen (CORS)?

Hallo,

ich mache gerade erste Geh-Versuche mit Blazor WebAssembly,
dabei komme ich irgendwie nicht weiter X(

Wie im Titel geschrieben versuche ich ein paar Strings aus einer funktionierenden ASP.NET Core-Web-API zu laden.

Mit folgendem Schnipsel versuche ich die Informationen im @code-Bereich der razor-Datei zu laden:


    protected override async Task OnInitializedAsync()
    {
        HttpClient http = new HttpClient();
        http.BaseAddress = new Uri("https://localhost:5005/");

        var TodoItems = await GetProductsAsync(http);
        One = TodoItems[0];
        Two = TodoItems[1];
        Three = TodoItems[2];
    }

    static async Task<List<string>> GetProductsAsync(HttpClient http)
    {
        List<string> item = null;
        HttpResponseMessage response = await http.GetAsync("api/StringItems");
        if (response.IsSuccessStatusCode)
        {
            item = await response.Content.ReadFromJsonAsync<List<string>>();
        }
        return item;
    }


Als Fehlermeldung bekomme ich 'TypeError: Failed to fetch'.
Das komische ist, das ich die Daten mit Postman sowie einer Test-ASP.NET Core-Web-App (mit obigen Schnipsel) problemlos lesen kann.

Alle Projekte laufen übrigens unter .NET 5

Gruß Jörg

16.834 Beiträge seit 2008
vor 3 Jahren

Die Verwendung des HttpClient ist hier generell falsch.
Der HttpClient sollte ausnahmslos über die Dependency Injection registriert und verwaltet werden; dafür gibts extra die HttpClientFactory.
Das steht auch dick und fett mit ner orangenen Warning Box in der Doku.

Das Problem am dieser Stelle wird sein, was viele JavaScript Entwickler schon ewig kennen: CORS.
Du musst Dich in Blazor an die Spielregeln der Browser-Security halten - und Domain-übergreifende Requests aus dem DOM sind erst einmal verboten (eben CORS).
Für Dich mag das mit "localhost" so aussehen, dass es identisch ist: aber die Endpoint-Identity betrifft den Host und den Port - und der muss hier zwangsläufig unterschiedlich sein und damit diesen Fehler auslösen.
Genauer gesagt muss der ansprechende Endpunkt mit CORS konfiguriert sein.

Siehe dazu die Doku (in der übrigens auch nochmal dick und fett die Sache mit der HttpClientFactory erwähnt).
Call a web API from ASP.NET Core Blazor und dann unter Cross-origin resource sharing (CORS)

J
Jörg Themenstarter:in
152 Beiträge seit 2009
vor 3 Jahren

Hi,

Schande über mein Haupt 8o

Ich hätte erwähnen sollen, dass ich die ersten Versuche mit Dependency Injection probiert habe.
Ich habe mich hierbei an der Anleitung von Dr. Holger Schwichtenberg orientiert:
Webprogrammierung mit Blazor WebAssembly

Aber da ich nicht weitergekommen bin, hab ich halt alles mögliche probiert.

So sieht es jetzt aus:


@inject HttpClient http

    protected override async Task OnInitializedAsync()
    {
        var TodoItems = await GetProductsAsync(http);

        One = TodoItems[0];
        Two = TodoItems[1];
        Three = TodoItems[2];
    }

    static async Task<List<string>> GetProductsAsync(HttpClient http)
    {
        List<string> item = null;
        //HttpResponseMessage response = await http.GetAsync("https://miraclelistbackend.azurewebsites.net/v2/About");
        HttpResponseMessage response = await http.GetAsync("https://localhost:5005/api/StringItems");
        if (response.IsSuccessStatusCode)
        {
            item = await response.Content.ReadFromJsonAsync<List<string>>();
        }
        return item;
    }

Wenn ich nun aber die Auskommentierung im Schnipsel auf die Seite 'Miraclelistbackend' ändere bekomme ich Texte 🤔

Ich peil es nicht

16.834 Beiträge seit 2008
vor 3 Jahren

Wenn ich nun aber die Auskommentierung im Schnipsel auf die Seite 'Miraclelistbackend' ändere bekomme ich Texte

Was willst Du damit sagen?

In Deiner Browser Developer Console sollte übrigens der Grund, wieso der FETCH fehl schlägt.
Mal reingeschaut?

J
Jörg Themenstarter:in
152 Beiträge seit 2009
vor 3 Jahren

Was willst Du damit sagen?

Damit meine ich, dass wenn ich nicht versuche auf meine API (localhost) zuzugreifen, sondern auf die andere Adresse im Internet, bekomme ich Daten, also liegt es wohl doch an meiner API.

In Deiner Browser Developer Console sollte übrigens der Grund, wieso der FETCH fehl schlägt.
Mal reingeschaut?

Da kommt keine Meldung in dem Moment des Fehlers.
(Du meinst doch das Konsolen-Fenster, welches sich beim Debuggen parallel zum Browser öffnet?)

16.834 Beiträge seit 2008
vor 3 Jahren

Und mit dem CORS haste keine Lust das zu beachten? 😉

Ich hab das trotzdem mal nachgestellt; und wie vermutet (und oben bereit erwähnt) bekomm ich entsprechend der Standard-Browsersicherhheit eine CORS Fehlermeldung, wenn ich gegen localhost versuche Daten zu holen.

Dazu die Fehlermeldung aus der Developer Console

Fehlermeldung:
Access to fetch at 'https://localhost:44308/data' from origin 'https://localhost:44359' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Setze ich den CORS Header auf Allow All - wie im Link beschrieben - geht es.
Wie gesagt; das ist ein Alltags-Thema bei der Arbeit mit APIs und Browser-Applikationen und den Sicherheitsstandards der Browser geschuldet.

J
Jörg Themenstarter:in
152 Beiträge seit 2009
vor 3 Jahren

Puh, das war eine schwere Geburt,
CORS war der springende Punkt.

Vielen Dank für deine Geduld mit mir 👍