首次渲染之前在 Blazor .NET 8 中获取 cookie

问题描述 投票:0回答:1

将我的 Blazor .Net6 项目迁移到 .Net8 后,我的 cookie 管理被破坏,并且我找不到解决方法。

由于主题化和避免 FOUC,我需要在首次渲染之前访问 HTTP 请求中的 cookie。我天真地尝试将 cookie 存储在注入根

ThemeService
组件中的作用域
App
中,因为只有根才能将
HttpContext
作为
CascadingParameter
访问。但是,注入到任何其他页面或组件中的相同
ThemeService
只会实例化 second 作用域服务...顺便说一句,我正在使用 RenderMode.InteractiveServer,并在 HeadOutlet/Router 级别全局禁用预渲染。

我的理论是,根

App
组件的 DI 范围基于原始 HTTP 请求,而所有其他组件 DI 范围都基于稍后才建立的 Blazor SignalR 连接。

所以我的问题是:在我的组件渲染之前,如何将 cookie 数据从第一个作用域传递到另一个作用域?

我唯一能想到的是创建一个单例服务,在其中存储 IP/cookie 或类似的字典,从根

App
组件插入它,然后以某种方式从 SignalR 获取 IP 并在辛格尔顿。这可能/可行吗?我真的很感激任何有关此问题的帮助或意见,它看起来很基本,但我很困惑。

提前致谢!

asp.net-core cookies blazor signalr blazor-server-side
1个回答
1
投票

您可以尝试:

@page "/"
@inject StateContainer StateContainer
@inject PersistentComponentState ApplicationState

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

CookieVal:@data

@code{

    [CascadingParameter]

    public HttpContext? httpContext { get; set; }

    private string data;

    private PersistingComponentStateSubscription persistingSubscription;


    protected override void OnInitialized()
    {
        StateContainer.OnChange += StateHasChanged;
        if (httpContext is not null)
        {

            var existTargetCookie = httpContext.Request.Cookies.TryGetValue("CookieKey", out data);
        }
        else
        {
            if(ApplicationState.TryTakeFromJson<string>(
            "Cookie", out data))
            {
                StateContainer.Property = data;
            }
            else
            {
                data = StateContainer.Property;
            }
        }
        persistingSubscription =
        ApplicationState.RegisterOnPersisting(PersistData);
    }

    private Task PersistData()
    {
        ApplicationState.PersistAsJson("Cookie", data);

        return Task.CompletedTask;
    }



    public void Dispose()
    {
        persistingSubscription.Dispose();
        StateContainer.OnChange -= StateHasChanged;
    }
    
}


public class StateContainer
{
    private string? savedString;

    public string Property
    {
        get => savedString ?? string.Empty;
        set
        {
            savedString = value;
            NotifyStateChanged();
        }
    }

    public event Action? OnChange;

    private void NotifyStateChanged() => OnChange?.Invoke();
}

结果:

© www.soinside.com 2019 - 2024. All rights reserved.