Search Results for

    Show / Hide Table of Contents

    Intent.Blazor.HttpClients

    This Intent Architect module generates HttpClients for Blazor applications.

    Getting started

    • In the Visual Studio IDE, if you haven't already done so, add a Blazor WebAssembly App to the same Visual Studio solution which is generated by Intent Architect: Visual Studio Solution Explorer with a Blazor WebAssembly App

    • In Intent Architect, open Visual Studio designer.

    • Create a new .NET Project with a name and folder structure which matches that of the Blazor project in the Visual Studio IDE: Create a new ".NET Project" context menu option in Intent Architect's Visual Studio Designer

    • Set the SDK for the project:

      • For a Blazor WebAssembly App set it to Microsoft.NET.Sdk.BlazorWebAssembly (if you don't see such an option, ensure you have at least 3.3.28 of the Intent.VisualStudio.Projects module installed).
      • For a Blazor Server App set it to Microsoft.NET.Sdk.Web.

      Selecting the SDK in the Visual Studio Designer

    • Within the desired location within the project you wish for the HttpClients and contracts to be generated, create a Blazor.HttpClient role: Create the "Blazor.HttpClient" role in Intent Architect's Visual Studio Designer

    • Install the Intent.Blazor.HttpClients module.

    Modelling service proxies

    • Ensure you already have one or more HTTP endpoints already modelled in the Services designer. In the following example CRUD operations have been created for an Invoice class: Services designer in Intent Architect
    • Open the Web Client designer and select the New Service Proxy context menu option, upon selecting which the mapping dialogue will show.
    • Select the available application and then select the endpoints to be included in the Service Proxy: Service Proxy Mapping Dialogue

    When you run the Software Factory, it will now generate the service proxies as well as supporting contracts and related types.

    Registering the HttpClients with the Blazor app's dependency injection

    In the Blazor project's Client/Program.cs file, add the following line just before the await builder.Build().RunAsync() line:

    builder.Configuration.Add(new MemoryConfigurationSource
    {
        InitialData = new Dictionary<string, string>
        {
            ["Urls:<applicationName>"] = "https://localhost:44321/"
        }
    });
    builder.Services.AddHttpClients(builder.Configuration);
    

    <applicationName> above will need to be replaced with application name as generated by Intent into the HttpClientConfiguration.cs file.

    https://localhost:44321/ should be replaced with the URL of your application's Api project, in development you can get this url from the Api project's Properties/launchsettings.json file.

    Note

    The above example is using a Memory Configuration Source to add the configuration, but any configuration source providing the appropriate key will work.

    The Program.cs file should now look something like this:

    using BlazorApp1;
    using BlazorApp1.HttpClients;
    using Microsoft.AspNetCore.Components.Web;
    using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
    using Microsoft.Extensions.Configuration.Memory;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace BlazorApp1
    {
        public class Program
        {
            public static async Task Main(string[] args)
            {
                var builder = WebAssemblyHostBuilder.CreateDefault(args);
                builder.RootComponents.Add<App>("#app");
                builder.RootComponents.Add<HeadOutlet>("head::after");
    
                builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
                builder.Configuration.Add(new MemoryConfigurationSource
                {
                    InitialData = new Dictionary<string, string>
                    {
                        ["Urls:Invoices"] = "https://localhost:44341/"
                    }
                });
                builder.Services.AddHttpClients(builder.Configuration);
    
                await builder.Build().RunAsync();
            }
        }
    }
    

    Attaching JWTs to outgoing requests

    The generated HttpClients will automatically include Bearer JWT headers in outgoing requests to secured endpoints, but they require security to already be configured for the Blazor application.

    Depending on your authentication and authorization strategy, you may be able to use one of the available options as documented by Microsoft and the generated HttpClients should just work with no additional configuration.

    If you have a custom authentication/authorization strategy, you may commonly encounter either or both of the following errors:

    No service for type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler' has been registered.

    To resolve this, add the following line to your Program.cs file:

    builder.Services.AddTransient<AuthorizationMessageHandler>();
    

    Unable to resolve service for type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider' while attempting to activate 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler'.

    You will need to create an implementation of IAccessTokenProvider and register it as a service.

    A simple implementation could be as follows:

    internal class AccessTokenProvider : IAccessTokenProvider
    {
        public ValueTask<AccessTokenResult> RequestAccessToken()
        {
            var accessToken = new AccessToken
            {
                Expires = DateTimeOffset.MaxValue,
                Value = "<your access token here>"
            };
    
            var result = new AccessTokenResult(AccessTokenResultStatus.Success, accessToken, null);
    
            return ValueTask.FromResult(result);
        }
    
        public async ValueTask<AccessTokenResult> RequestAccessToken(AccessTokenRequestOptions options)
        {
            return await RequestAccessToken();
        }
    }
    

    You would customize the implementation to populate AccessToken's Value with an actual JWT.

    You can register your implementation in Program.cs with the following (or similar) code:

    builder.Services.AddScoped<IAccessTokenProvider, AccessTokenProvider>();
    

    You can also review Microsoft's documentation on covering additional Blazor security scenarios for more information.

    Adding CORS to your Api project

    If your Blazor App is hosted on a different BaseUrl to that of your API, the browser will block these cross-origin requests unless you configure CORS in the API project.

    You can install the Intent.Modules.AspNetCore.Cors module in the same Intent Architect Application as your API, run the Software Factory and it will then apply the required updates to enable CORS.

    Using the service proxy in a Razor file

    From within a .razor file it is now possible to inject HttpClients and call methods from them, the following is a simple example:

    @page "/fetchdata"
    @using BlazorApp1.HttpClients
    @using BlazorApp1.HttpClients.InvoicesService
    @inject IInvoicesService Http
    
    <PageTitle>Invoices</PageTitle>
    
    <h1>Invoices</h1>
    
    <p>This component demonstrates fetching data from the server.</p>
    
    @if (_invoices == null)
    {
        <p><em>Loading...</em></p>
    }
    else
    {
        <table class="table">
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Number</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var invoice in _invoices)
                {
                    <tr>
                        <td>@invoice.Id</td>
                        <td>@invoice.Number</td>
                    </tr>
                }
            </tbody>
        </table>
    }
    
    @code {
        private List<InvoiceDto>? _invoices;
    
        protected override async Task OnInitializedAsync()
        {
            _invoices = await Http.GetInvoicesAsync();
        }
    }
    

    If you now run both projects, the page with the HttpClient should now be able to fetch and render the data.

    • Edit this page
    ☀
    ☾
    In this article
    Back to top Copyright © 2017-, Intent Software Pte Ltd.