How to use the HttpContext object in server-side Blazor to retrieve information about the user, user agent

The fiction that the HttpContext object can't be used with Blazor Server App, has been long propagated on Stackoverflow, and it is high time to pension it off.

It is true that the HttpContext is not available when a WebSocket connection is in operation, but this must be clear: When you type an url and press the enter button, the connection to your server-side Blazor app is an HTTP connection, and not a WebSocket connection.

Thus, your app can access and use the HttpContext in the same way it is used in a Razor Pages App or a MVC App, including getting the User Agent and an IP Address. The following code sample demonstrates how to use the HttpContext to get the User Agent and IP Address natively, without using JSInterop which should be used as a last resort, and pass the extracted values to the App component.

  1. Add a file to the Pages folder and name it _Host.cshtml.cs.
  2. Add this code to the file:
public class HostModel: PageModel
{
    private readonly IHttpContextAccessor _httpContextAccssor;
    
    public HttpContextFeatureModel(IHttpContextAccessor httpContextAccssor)
    {
        _httpContextAccssor = httpContextAccssor;    
    }

    public string UserAgent { get; set; }
    public string IPAddress { get; set; }
    
    // The following links may be useful for getting the IP Adress:
    // https://stackoverflow.com/questions/35441521/remoteipaddress-is-always-null
    // https://stackoverflow.com/questions/28664686/how-do-i-get-client-ip-address-in-asp-net-core
    
    public void OnGet()
    {
        UserAgent = _httpContextAccssor.HttpContext.Request.Headers["User-Agent"];
        // Note that the RemoteIpAddress property returns an IPAdrress object 
        // which you can query to get required information. Here, however, we pass 
        // its string representation
        IPAddress = _httpContextAccssor.HttpContext.Connection.RemoteIpAddress.ToString();  
    }
}

You may need one or more of these usings:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
  1. Add the following line to your Host.cshthml page (on top of the page near to the usings and that stuff):
@model HostModel
  1. In the App component, define two parameter properties that will get and store the User Agent and IP Address passed to it from the component tag located in _Host.cshtml.

App.razor:

<p>UserAgent: @UserAgent</p>
<p>IPAddress: @IPAddress</p>

@code
{
    [Parameter]
    public string UserAgent { get; set; }

    [Parameter]
    public string IPAddress { get; set; }
}
  1. In _Host.cshtml update the component tag like this (This method is outdated now):
<app>
    <component type="typeof(App)" render-mode="ServerPrerendered" param-UserAgent="@Model.UserAgent" param-IPAddress="@Model.IPAddress" />
</app>

In current Blazor server side apps, this can be done like this:

<div>
    @(await Html.RenderComponentAsync<App>(RenderMode.Server, new { IPAddress = Model.IPAddress, UserAgent = Model.UserAgent }))
</div>
  1. Add services.AddHttpContextAccessor(); to Startup's ConfigureServices method to enable access to the HttpContext.

That is all. You can add the Identity UI to your Blazor Server App as well and apply the same procedure shown above to extract the claims principal from the HttpContext, after the user has authenticated (do that for learning purpose only, as you should use the AuthenticationStateProvider instead).

Here's also a link to a question I've just answered about setting the consent cookie in a Blazor Server App.