I'm new to Blazor and having an issue with a component.
In OnInitializedAsync
, we're making a call to get the data for the component. We have prerendering enabled
.
By default, so OnInitializedAsync
is getting called twice. As I understand it, this is to be expected. However when we make the http calls we have a method in place to add the authorization details to the request. The first time OnInitializedAsync
is called, it works fine but on the second call the contextAccessor
is null and as such we can't get the roles information we need. Not sure how to proceed.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request), "Message cannot be null.");
}
// Prepare the request message copy to be modified
MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue);
request = buffer.CreateMessage();
string[] userRoles;
System.Security.Claims.ClaimsPrincipal user = Utilities.HttpContext.Current?.User;
if (user == null)
{
IHttpContextAccessor contextAccessor = ServiceProviderHolder.ServiceProvider.GetService<IHttpContextAccessor>();
user = contextAccessor?.HttpContext?.User;
if (user != null)
{
AddFromPrincipal(request, user);
}
}else{
AddFromPrincipal(request, user);
}
return null;
}
private static void AddFromPrincipal(Message request, ClaimsPrincipal user)
{
string roles = user.GetRoles();
string loginId = user.GetLoginId();
string firstName = user.GetFirstName();
string lastName = user.GetLastName();
string email = user.GetEmail();
string lsUniqueId = user.GetUniqueId();
string primaryUniqueId = user.GetPrimaryUniqueId();
IdentityHeader idHeader = new(lsUniqueId, roles, string.Empty, loginId, firstName, lastName, email, primaryUniqueId, $"{firstName} {lastName}");
request.Headers.Add(MessageHeader.CreateHeader(CustomHeaderNames.CustomHeaderName, CustomHeaderNames.CustomHeaderNamespace, idHeader));
}
I'm new to Blazor and having an issue with a component.
In OnInitializedAsync
, we're making a call to get the data for the component. We have prerendering enabled
.
By default, so OnInitializedAsync
is getting called twice. As I understand it, this is to be expected. However when we make the http calls we have a method in place to add the authorization details to the request. The first time OnInitializedAsync
is called, it works fine but on the second call the contextAccessor
is null and as such we can't get the roles information we need. Not sure how to proceed.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request), "Message cannot be null.");
}
// Prepare the request message copy to be modified
MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue);
request = buffer.CreateMessage();
string[] userRoles;
System.Security.Claims.ClaimsPrincipal user = Utilities.HttpContext.Current?.User;
if (user == null)
{
IHttpContextAccessor contextAccessor = ServiceProviderHolder.ServiceProvider.GetService<IHttpContextAccessor>();
user = contextAccessor?.HttpContext?.User;
if (user != null)
{
AddFromPrincipal(request, user);
}
}else{
AddFromPrincipal(request, user);
}
return null;
}
private static void AddFromPrincipal(Message request, ClaimsPrincipal user)
{
string roles = user.GetRoles();
string loginId = user.GetLoginId();
string firstName = user.GetFirstName();
string lastName = user.GetLastName();
string email = user.GetEmail();
string lsUniqueId = user.GetUniqueId();
string primaryUniqueId = user.GetPrimaryUniqueId();
IdentityHeader idHeader = new(lsUniqueId, roles, string.Empty, loginId, firstName, lastName, email, primaryUniqueId, $"{firstName} {lastName}");
request.Headers.Add(MessageHeader.CreateHeader(CustomHeaderNames.CustomHeaderName, CustomHeaderNames.CustomHeaderNamespace, idHeader));
}
Share
Improve this question
edited Feb 6 at 7:43
Tiny Wang
16k2 gold badges18 silver badges38 bronze badges
asked Feb 5 at 20:03
TrevorGoodchildTrevorGoodchild
1,0602 gold badges27 silver badges55 bronze badges
3
- May I know whether the issue still exist if you disable prerendering? And may I know the .Net version and render mode used in your blazor application? Are you working on blazor server/blazor web assembly/blazor web app? – Tiny Wang Commented Feb 6 at 4:12
- We are using .NET 8 and rendermode is InteractiveServer using Blazor Server – TrevorGoodchild Commented Feb 6 at 13:43
- Yes thank you for your confirmation, the sample I shared comes from this document and I think this shall be helpful to you. – Tiny Wang Commented Feb 7 at 1:29
1 Answer
Reset to default 1We have PersistentComponentState
to persist prerendered state, you just need to use PersistAsJson method to serializes instance as JSON and persists it under the given key.
Here's the code sample shared in the document.
@implements IDisposable
@inject PersistentComponentState ApplicationState
...
@code {
private {TYPE} data;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistData);
if (!ApplicationState.TryTakeFromJson<{TYPE}>(
"{TOKEN}", out var restored))
{
data = await ...;
}
else
{
data = restored!;
}
}
private Task PersistData()
{
ApplicationState.PersistAsJson("{TOKEN}", data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
In the meantime, IHttpContextAccessor
is not recommended as it is not something that works with Signalr apps or Blazor apps for that matter. See this case. And as a replacement, AuthenticationStateProvider shall be a good option to get user information.