Search code examples
asp.net-corecookiesblazorsignalrblazor-server-side

Get cookie in Blazor .NET 8 before first render


After migrating my Blazor .Net6 project to .Net8 my cookie management is broken and I can't find a way around it.

Due to theming and avoiding FOUC I need to access a cookie in the HTTP request before first render. Naively I have tried storing the cookie in a scoped ThemeService injected in the root App component, since only the root can access the HttpContext as a CascadingParameter. However, the same ThemeService injected into any other page or component will just instantiate a second scoped service... I'm using RenderMode.InteractiveServer with prerender disabled globally at the HeadOutlet/Router level, by the way.

My theory is that the DI scope of the root App component is based on the original HTTP request, while all other component DI scopes are based on the Blazor SignalR connection which is only established later.

So my question is: How can I pass cookie data from the first scope to the other, before my components render?

The only thing I can think of is creating a Singleton service where I store a dictionary of IP/cookie or similar, insert it from the root App component and then somehow get hold of the IP from SignalR and look it up in the Singleton. Is that even possible/viable? I'd really appreciate any help or input on this one, it seems so basic but I'm stumped.

Thanks in advance!


Solution

  • I figured out a workaround. Injecting the state container directly into the App component never worked out for me; it always instantiates in non-user-scope and never re-initializes, so the persist pattern is not viable.

    Eventually I just stored the cookie as a regular member of the App component and transferred it by normal parameter binding to a child component. That child component does render in user-scope, so I was able to inject the state container there.

    It's not as clean and reusable as I would have liked, but at least it works.