How do I access HttpContext in Server-side Blazor?

后端 未结 4 1881
感动是毒
感动是毒 2020-12-06 00:40

I need to access HttpContext in a page (.cshtml) and in particular a request and then a cookie. Despite available, HttpContextAccessor always has

相关标签:
4条回答
  • 2020-12-06 00:59

    It depends what you want to access the HttpContext for.

    Should you want to access authentication or user info, consider using the AuthenticationStateProvider instead:

    @page "/"
    @using System.Security.Claims
    @using Microsoft.AspNetCore.Components.Authorization
    @inject AuthenticationStateProvider AuthenticationStateProvider
    
    <h3>ClaimsPrincipal Data</h3>
    
    <button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
    
    <p>@_authMessage</p>
    
    @if (_claims.Count() > 0)
    {
        <ul>
            @foreach (var claim in _claims)
            {
                <li>@claim.Type &ndash; @claim.Value</li>
            }
        </ul>
    }
    
    <p>@_surnameMessage</p>
    
    @code {
        private string _authMessage;
        private string _surnameMessage;
        private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();
    
        private async Task GetClaimsPrincipalData()
        {
            var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.Identity.IsAuthenticated)
            {
                _authMessage = $"{user.Identity.Name} is authenticated.";
                _claims = user.Claims;
                _surnameMessage = 
                    $"Surname: {user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value}";
            }
            else
            {
                _authMessage = "The user is NOT authenticated.";
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-06 01:04

    Add the following to Blazor.Web.App.Startup.cs:

    services.AddHttpContextAccessor();
    

    You also need this in <component-name>.cshtml

    @using Microsoft.AspNetCore.Http
    @inject IHttpContextAccessor httpContextAccessor
    

    Note: At the time when this answer was written, accessing the HttpContext was done as described above. Since then, Blazor has been under rapid development, and has fundamentally changed. It is definitely deprecated the usage described above, but alas, you can still do the above, which is legitimate and right, if you access the HttpContext from a .cshtml page. This has not changed... Thus the only place from which you can access the HttpContext, without even adding the IHttpContextAccessor to the DI container, is the _Host.cshtml file, which is a Razor Pages file, with the .cshtml extension. When the code in this file is executed, Blazor is still not born, and the execution of this file will be serving the Blazor Server App. Please, see this answer as to how to do it properly...

    Hope this helps...

    0 讨论(0)
  • 2020-12-06 01:06

    Please note that the documentation explicitly states that IHttpContextAccessor should not be used for Blazor apps: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-3.1#blazor-and-shared-state

    (This does not mean that in your particular case it will not work for a particular scenario. But as you are anyway only able to get the cookie from the first request - once SignalR takes over the are no cookies anymore - you should maybe get the value when _Host.cshtml is renderend, and pass it on as a string value to the Blazor components from there.)

    0 讨论(0)
  • 2020-12-06 01:14

    blazor.Sever to Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddServerSideBlazor<Client.Startup>();
    
        // HttpContextAccessor
        services.AddHttpContextAccessor();
        services.AddScoped<HttpContextAccessor>();
    }
    

    blazor.Shared

    public class HttpContextAccessor
    {
       private readonly IHttpContextAccessor _httpContextAccessor;
    
       public HttpContextAccessor(IHttpContextAccessor httpContextAccessor)
       {
            _httpContextAccessor = httpContextAccessor;
       }
    
       public HttpContext Context => _httpContextAccessor.HttpContext;
    }
    

    blazor.Client to App.cshtml

    @inject blazor.Shared.HttpContextAccessor HttpContext
    <Router AppAssembly=typeof(Program).Assembly />
    
    @functions 
    {      
        protected override void OnInit()
        {
           HttpContext.Context.Request.Cookies.**
    
           // Or data passed through middleware in blazor.Server
           HttpContext.Context.Features.Get<T>()
        }
    }
    

    Credits: https://github.com/aspnet/Blazor/issues/1554

    0 讨论(0)
提交回复
热议问题