Making HTTP Requests in Blazor WebAssembly Apps

You are currently viewing Making HTTP Requests in Blazor WebAssembly Apps

In my previous post Making HTTP Requests in Blazor Server Apps, I covered different techniques of making HTTP requests in Blazor Server apps where you have access to all .NET libraries and components. If you are creating a Blazor WebAssembly App, then your code is running on the client within the browser sandbox and your options are somehow limited. In this tutorial, I will show you how you can make HTTP requests from Blazor WebAssembly Apps.

Overview of HttpClient in Blazor WebAssembly Apps

Blazor WebAssembly apps call web APIs using a preconfigured HttpClient service. This preconfigured HttpClient is implemented using the use browser Fetch API  and has some limitations. HttpClient can also use Blazor JSON helpers or HttpRequestMessage object to make API calls. By default, the API call requests can only be made to the same server of origin but you can call third-party APIs available on other servers if they support Cross-origin resource sharing (CORS).

The System.Net.Http.Json namespace provides extension methods for HttpClient that perform automatic serialization and deserialization using System.Text.Json. These extension methods send requests to a Web API URI and process the response accordingly. The common methods include:

  • GetFromJsonAsync: Sends an HTTP GET request and parses the JSON response body to create an object.
  • PostAsJsonAsync: Sends a POST request to the specified URI containing the value serialized as JSON in the request body.
  • PutAsJsonAsync: Sends an HTTP PUT request, including JSON-encoded content.
READ ALSO:  Dockerize ASP.NET Core API and SQL Server

To understand how to use these methods along with HttpClient, we need to create two projects. The first project will be a Web API project that will expose a Web API for clients. The second project will be Blazor WebAssembly App that will make HTTP requests to a Web API created in the first project.

Implementing an ASP.NET Core Web API

In this section, we will implement a Web API with Cross-origin resource sharing (CORS) support so that this API can be called by Blazor WebAssembly apps. Create a new Web API project BlazorClientWebAPI in Visual Studio 2019. We will create a simple API that will return the list of products so let’s first create a Models folder in the project and add the following Product class to it.

Product.cs

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Next, create a Controllers folder and add the following ProductsController in it. The controller is simply returning some fake product data from the GetProducts method.

ProductsController.cs

[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult GetProducts()
    {
        var products = new List<Product>()
        {
            new Product()
            {
                Id = 1,
                Name = "Wireless Mouse",
                Price = 29.99m
            },
            new Product()
            {
                Id = 2,
                Name = "HP Headphone",
                Price = 79.99m
            },
            new Product()
            {
                Id = 3,
                Name = "Sony Keyboard",
                Price = 119.99m
            }
        };

        return Ok(products);
    }
}

If you will run your project and try to access the API using the URI api/products in the browser, you should be able to see the product data returned in JSON format.

Products API Response for Blazor WebAssembly HttpClient

Enable CORS in ASP.NET Core Web API

By default, browser security doesn’t allow a web page to make requests to a different domain other than the one from where the web page is served. This restriction is called the same-origin policy. If we want Blazor WebAssembly Apps or other client apps to consume the above Web API then we have to enable cross-origin resource sharing (CORS). Open the Startup.cs file and call the AddCors method in the ConfigureServices method.

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(policy =>
    {
        policy.AddPolicy("CorsPolicy", opt => opt
            .AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod());
    });

    services.AddControllers();
}

Also add the following line in the Configure method of Startup.cs file

app.UseCors("CorsPolicy");

For detailed information on CORS with ASP.NET Core apps, see Enable Cross-Origin Requests (CORS) in ASP.NET Core.

READ ALSO:  Building Blazor WebAssembly Apps with Clean Architecture

Implementing Blazor WebAssembly App

Add a new Blazor WebAssembly App project BlazorClientWebAPIsDemo in the same solution in which you created the above Web API project.

The first thing we need to make sure of is that we have the reference of System.Net.Http.Json in the project file. If it’s not available then you can add the reference.

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
   <PropertyGroup>
      <TargetFramework>net5.0</TargetFramework>
   </PropertyGroup>
   <ItemGroup>
      <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.1" />
      <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.1" PrivateAssets="all" />
      <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
   </ItemGroup>
</Project>

Next, we need to configure the HttpClient service in Program.cs file. Make sure to provide the base address of the Web APIs you want to call from Blazor WebAssembly Apps

Program.cs

public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<App>("#app");

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

    await builder.Build().RunAsync();
}

To consume the products API, let’s create a Products.razor component in the Pages folder. The view is very straightforward as it is simply iterating the list of products and displaying them using a simple HTML table.

Products.razor

@page "/products"

<h1>Products</h1>

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

Create a Products.razor.cs code-behind file and inject the configured HttpClient instance in the class as a private member. Finally, use the GetFromJsonAsync method to call the products API.

Products.razor.cs

public partial class Products
{
    private List<Product> products;

    [Inject]
    private HttpClient Http { get; set; }

    protected override async Task OnInitializedAsync()
    {
        products = await Http.GetFromJsonAsync<List<Product>>("products");
    } 
}

You also need to create a local copy of the Product class in the Blazor WebAssembly project to deserialized the results of the products API into a list of product objects.

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Run the project and you will see the page with products loaded from a backend Web API.

READ ALSO:  A Beginner's Guide to GraphQL
Makking HTTP Requests to Web API from Blazor WebAssembly App

This Post Has 2 Comments

  1. Graeme

    Hi
    I have tried this as best to my knowledge but cannot get it to work – do you have a solution that I can download?
    Thanks

Leave a Reply