TroelsGP
TroelsGP

Reputation: 741

How to avoid System.TypeLoadException unhandled exception in browser when loading Blazor client-side application

I have a client-side Blazor application, and when I try to run it for debugging from Visual Studio 2019 16.3.0 Preview 2.0, I get this error message in the Chrome browser (seen when debugging using Shift-Alt-D):

blazor.webassembly.js:1 WASM: System.TypeLoadException: Could not resolve type with token 01000020 from typeref (expected class 'Microsoft.AspNetCore.Blazor.HttpClientJsonExtensions' in assembly 'Microsoft.AspNetCore.Blazor, Version=0.7.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60')

I have set a breakpoint as early I could in Main in Program.cs, but this does not get hit.

I am using Blazor version 3.0.0-preview8.19405.7. I have been searching for a solution to this problem, but all articles seem to address other issues than mine.

The issue seems to be about Json and HttpClient, so I thought it might have something to do with the upgrade since it was mentioned in the procedure: https://devblogs.microsoft.com/aspnet/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-8/

But I actually did not use Json succesfully before upgrading (it was under development), so I don't know for sure if it has something to do with this.

Edit: I have tried to remove the two lines from the code (but kept the reference to Microsoft.AspNetCore.Blazor.HttpClient in the project file):

result = await httpClient.GetJsonAsync<bool>("uri");

and

await httpClient.PutJsonAsync("uri", value);

This solved the problem, but will of cause leave me without any calls to my backend.

So how can I use httpClient? Or which alternatives do I have?

Edit:

I am creating httpClient using dependency injection in my constructor

public class ServiceProxy : IServiceProxy
{
    private readonly HttpClient httpClient;
    public ServiceProxy(IHttpClientFactory httpClientFactory)
    {
        httpClient = httpClientFactory.CreateClient();
        httpClient.BaseAddress = new Uri("https://localhost:12345"), UriKind.Absolute);
    }

    public async Task<bool> GetResultAsync()
    {
        bool result
        try
        {
            result = await httpClient.GetJsonAsync<bool>("resource");
        }
        catch (HttpRequestException httpRequestException)
        {
            throw new ConnectionException(string.Format("Http Request failed: {0}", httpRequestException.Message), httpRequestException);
        }
        return result;
    }
}

The dependencies are injected from my startup class

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        services.AddTransient<IServiceProxy, ServiceProxy>();
    }
}

Upvotes: 3

Views: 1884

Answers (3)

TroelsGP
TroelsGP

Reputation: 741

I have discovered the root cause of this problem and thereby found a solution for it.

I upgraded my Visual Studio 2019 to 16.4.0 Preview 1.0, and then something broke, which did not break before. And when consolidating my NuGet dependencies I was very surprised that one of my .NET Standard dependency projects actually had a reference to Blazor 0.7.0, which was older than the Preview 8 version I was upgrading from.

This reference was probably the cause of my pain! When that reference was removed, I could not call my httpClient.PutJsonAsync and httpClient.GetJsonAsync any more, because this is probably only implemented in the Blazor version of the HttpClient.

I rewrote my library to use httpClient.PutAsync and httpClient.GetAsync and using Newtonsoft.Json to serialize and deserialize. After fixing some CORS issues in addition, it worked.

Upvotes: 2

Zsolt Bendes
Zsolt Bendes

Reputation: 2589

Client side blazor does not support IHttpClientFactory. Client side HttpClient is not the same as in server side or other version. It is a wrapper of the XMLHttpRequest in the browser. (Additionally layered over typescript)

[Blazor client-side apps call web APIs using a preconfigured HttpClient service. Compose requests, which can include JavaScript Fetch API options, using Blazor JSON helpers or with HttpRequestMessage.

Blazor server-side apps call web APIs using HttpClient instances typically created using IHttpClientFactory. For more information, see Make HTTP requests using IHttpClientFactory in ASP.NET Core.]1

On client side the HttpClient is out of the box included in the DI. You can use that to make http calls.

Inject it to code into constructor:

private readonly HttpClient _httpClient;

public YourClassName(HttpClient httpClient)
{
    _httpClient = httpClient;
}

//Use the _httpClient in other methods as usual

Injecting into a property

[Inject]
public HttpClient MyHttpClient { get; set; }

Injecting into a blazor page

@inject HttpClient MyHttpClient

code {
   //Use the MyHttpClientin other methods as usual
}

Additional resources for DI in blazor

Upvotes: 0

Charlie  P.
Charlie P.

Reputation: 23

When I run into issues like this, I delete the bin and obj folders while my project is closed. I also delete all nuget packages and install them again.

I hope this helps.

Upvotes: 1

Related Questions