How to resolve "TypeError: Failed to fetch" error on Blazor?
Asked Answered
E

4

30

I am trying to send an HTTP request from my Blazor app to my ASP.NET Core API. I have breakpoints everywhere. The application gives an exception right after the action method on the API controller returns. I am familiar with .NET overall, however, I could not decipher the error message.

Blazor http call:

var response = await _httpClient.GetStreamAsync($"Customer/GetAllCustomers");

ASP.NET Core API Controller action:

[HttpGet]
[Route("GetAllCustomers")]
public async Task<IEnumerable<Customer>> GetAllCustomersAsync()
{
    return await _service.GetAllCustomersAsync();
}

Error stack:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: TypeError: Failed to fetch
WebAssembly.JSException: TypeError: Failed to fetch
  at System.Net.Http.WebAssemblyHttpHandler.doFetch (System.Threading.Tasks.TaskCompletionSource`1[TResult] tcs, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x301ab40 + 0x00a30> in <filename unknown>:0 
  at System.Net.Http.WebAssemblyHttpHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2ff3590 + 0x00174> in <filename unknown>:0 
  at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2ff1e98 + 0x00160> in <filename unknown>:0 
  at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2fc8a98 + 0x00182> in <filename unknown>:0 
  at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) <0x301ff08 + 0x00134> in <filename unknown>:0 
  at System.Net.Http.HttpClient.FinishGetStreamAsync (System.Threading.Tasks.Task`1[TResult] getTask) <0x2ffa720 + 0x000cc> in <filename unknown>:0 
  at WebClient.Services.LectureVideoService.GetAllLectureVideos (Content.Data.Enums.LessonType lessonType) [0x00040] in D:\AlbidersSoftware\CSharp\Albiders Content MS\Albiders\WebClient\Services\LectureVideoService.cs:21 
  at WebClient.Pages.MathAccList.OnInitializedAsync () [0x00026] in D:\AlbidersSoftware\CSharp\Albiders Content MS\Albiders\WebClient\Pages\MathAccList.razor:18 
  at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x2bed718 + 0x0013a> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x2e3a0b0 + 0x000b6> in <filename unknown>:0 
Evidential answered 1/12, 2020 at 4:41 Comment(1)
I received an identical error, when accessing a Web API call in which CORS was not properly configured on the server side. The error did not occur when calling the same Web API endpoint, from a unit test, only when trying to call it from Blazor WASM.Nodose
B
14

Unhandled exception rendering component: TypeError: Failed to fetch

WebAssembly.JSException: TypeError: Failed to fetch

I did a test to make request(s) from my Blazor WebAssembly app to action method with testing data, which works well on my side.

[Route("[controller]")]
[ApiController]
public class CustomerController : ControllerBase
{
    [HttpGet]
    [Route("GetAllCustomers")]
    public async Task<IEnumerable<Customer>> GetAllCustomersAsync()
    {
        //for testing purpose

        return new List<Customer> { new Customer { Id = 1, Name = "Test1" }, new Customer { Id = 2, Name = "Test2" } };

        //return await _service.GetAllCustomersAsync();
    }
}

GetAllCustomers.razor

@page "/getallcustomers"
@using BlazorWasmApp1.Shared
@inject HttpClient _httpClient

<h3>Customer List</h3>

@if (customers == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var customer in customers)
            {
                <tr>
                    <td>@customer.Id</td>
                    <td>@customer.Name</td>
                </tr>
            }
        </tbody>
    </table>
}


@code {
    private Customer[] customers;

    protected override async Task OnInitializedAsync()
    {
        //call external API
        //_httpClient.BaseAddress = new Uri("https://localhost:44312/");


        //your API action would return a collection of Customer
        //you can try to call .GetFromJsonAsync<Customer[]>() to get the expected data
        //rather than get stream
        customers = await _httpClient.GetFromJsonAsync<Customer[]>($"Customer/GetAllCustomers");
    }
}

Test Result

enter image description here

To troubleshoot the issue, please try:

  1. check the URL of your request in browser developer tool Network tab, and make sure you are making request to correct endpoint

  2. if your ASP.NET Core Web API project is hosting on separate site, please make sure you configured and enabled CORS to allow request(s) from your Blazor WebAssembly app, and make sure that API is running

Brushwork answered 1/12, 2020 at 6:36 Comment(0)
S
9

Also check if your api is requesting from HTTP, change it to https: it will work

enter image description here

Silicone answered 3/2, 2021 at 2:47 Comment(0)
S
2

EDIT NOTE: I just realised that my original answer was a red-herring, so I have deleted it and replaced it. The actual cause of my error is quite different to your question, but I'll provide a summary of resolution here because it was the first post that came up with this error message and it might help someone else troubleshoot it.

I am building a Web Assembly Hosted project, but with multiple clients and have been trialing combining AddMicrosoftIdentityWebApi and AddMicrosoftIdentityWebApp in my Server project as per following.

Program.cs (Server Project)

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))

Everything worked fine with just AddMicrosoftIdentityWebApi. However, when I added AddMicrosoftIdentityWebApp and tried to call my api from the client, I got the error that you identified.

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: TypeError: Failed to fetch
System.Net.Http.HttpRequestException: TypeError: Failed to fetch
 ---> System.Runtime.InteropServices.JavaScript.JSException: TypeError: Failed to fetch
   at System.Net.Http.BrowserHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.BrowserHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
   at System.Net.Http.Json.HttpClientJsonExtensions.<GetFromJsonAsyncCore>d__13`1[[BlazorApp14.Shared.WeatherForecast[], BlazorApp14.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at BlazorApp14.Client.Pages.FetchData.OnInitializedAsync() in C:\Temp\BlazorApp14\BlazorApp14\Client\Pages\FetchData.razor:line 50
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

If I had looked more closely, I would have seen that my error is not quite the same as yours, but anyway.....

I then noticed that there was an additional error showing in Dev Tools on the browser.

Access to fetch at 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=0e5f2876-c................... 
redirected from 'https://localhost:5001/WeatherForecast') from origin 'https://localhost:5001' has been blocked by CORS policy:
 Response to preflight request doesn't pass access control check: 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.

This sent me down another rabbit-hole and I setup Cors etc. on my WebApi project, which did not help.

I then thought that perhaps using the same registered AzureAD application in the AddMicrosoftIdentityWebApi and AddMicrosoftIdentityWebApp calls. However, this was not the problem either.

It turns out that the [Authorize] attribute on my controller couldn't choose which Authentication scheme to use and chose the "wrong" one. The simple fix to my error was to explicitly call out the Authentication Scheme in the Authorize attribute as shown following.

   [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
Spay answered 2/11, 2022 at 19:0 Comment(0)
W
0

I had this issue today, no code changes, Client just stopped connecting to Server wss. Steps that may have lead to this were while I was working in another solution, I reset the local nuget cache. And Visual Studio ran the update installer.
The fix was to close the Blazor solution and run this PowerShell gem on the Blazor solution folder, erasing the bin/obj folders for all projects.

Wren answered 12/7 at 15:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.