-
-
Notifications
You must be signed in to change notification settings - Fork 408
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InvalidOperationException in Blazor 8 state manager #3737
Comments
@mtavares628 I did the following:
I am not seeing any exceptions in the console or host window where the web server is running. How are you seeing these exceptions? |
I wonder what is different in your app from my test. My config: builder.Services.AddCsla(o=>o
.AddAspNetCore()
.AddServerSideBlazor()); My pages: @inject Csla.Blazor.State.StateManager stateManager
...
protected override async Task OnInitializedAsync()
{
await stateManager.InitializeAsync();
} Because I (and you?) have no wasm pages, at no point should session be "checked out" and so at no point should the task completion source code even be invoked. Are you seeing the exceptions as a result of a data portal call, or something else? |
It appears to be happening in LocalProxy.cs on line 40 of InitializeContext where it tries to get the ApplicationContext: private void InitializeContext(out IDataPortalServer _portal, out IServiceScope _logicalServerScope, out ApplicationContext _logicalServerApplicationContext)
{
IServiceProvider provider = CallerApplicationContext.CurrentServiceProvider;
if (Options.UseLocalScope && CallerApplicationContext.LogicalExecutionLocation == ApplicationContext.LogicalExecutionLocations.Client && CallerApplicationContext.IsAStatefulContextManager)
{
_logicalServerScope = CallerApplicationContext.CurrentServiceProvider.CreateScope();
provider = _logicalServerScope.ServiceProvider;
provider.GetRequiredService<IRuntimeInfo>().LocalProxyNewScopeExists = true;
}
else
{
_logicalServerScope = null;
}
_logicalServerApplicationContext = provider.GetRequiredService<ApplicationContext>();
_portal = provider.GetRequiredService<IDataPortalServer>();
} If you are around, I can show you, just let me know. |
@mtavares628 I am available for about an hour - waiting for a flight to board. Meet me on Discord? |
@rockfordlhotka So I've been troubleshooting further and it seems that it definitely has something to do with the scoped service provider in that InitializeContext method of LocalProxy. When I look at the state of _logicalServerApplicationContext in that method, the Identity of the ClaimsPrincipal is null. I'm not sure why. But if I use the existing CallerApplicationContext service provider to get the _logicalServerApplicationContext, then the Identity is there. In tracking why my application worked in a prior pre-release, it looks like the pull request which changed things appears to be #3632 in particular this commit from it: d3aa7cc This was where IntializeContext was changed. |
If it has something todo with the |
@StefanOssendorf - In performing more testing, I don't think the issue has anything to do with the StateManager code with TaskCompletionSource in it. @rockfordlhotka - I've dug a little deeper and the inner message of the InvalidOperationException is:
I've traced this to me using a custom AuthenticationStateProvider that inherits from ServerAuthenticationStateProvider. All I'm doing with it is adding in roles as claims: public class DadAuthenticationStateProvider : ServerAuthenticationStateProvider
{
private IUserRoleStore<DadUser> _roleStore;
public DadAuthenticationStateProvider(IUserRoleStore<DadUser> roleStore)
{
_roleStore = roleStore;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var authState = await base.GetAuthenticationStateAsync();
if (authState.User.Identity != null && authState.User.Identity.IsAuthenticated)
{
var identity = (ClaimsIdentity)authState.User.Identity;
int UserId;
if (int.TryParse(identity.FindFirst("sub")?.Value, out UserId))
{
var roleList = (List<string>)(await _roleStore.GetRolesAsync(new DadUser() { Id = UserId }, new CancellationToken(false)));
foreach (string item in roleList)
{
if (!identity.HasClaim("role", item))
{
identity.AddClaim(new Claim("role", item));
}
}
}
}
return authState;
}
} The exception is actually being thrown In the InitializeUser method of ApplicationContextManagerInMemory.cs: private void InitializeUser()
{
Task<AuthenticationState> task = default;
try
{
task = AuthenticationStateProvider.GetAuthenticationStateAsync();
}
catch (InvalidOperationException ex)
{
task = Task.FromResult(new AuthenticationState((ClaimsPrincipal)UnauthenticatedPrincipal));
string message = ex.Message;
if (message.Contains(nameof(AuthenticationStateProvider.GetAuthenticationStateAsync))
&& message.Contains(nameof(IHostEnvironmentAuthenticationStateProvider.SetAuthenticationState)))
{
SetHostPrincipal(task);
}
else
{
throw;
}
}
AuthenticationStateProvider_AuthenticationStateChanged(task);
} While it does have a try-catch for an InvalidOperationException to check for this specific error, the catch isn't being hit because it is being captured within the task object and not immediately thrown at that point. The solution to that would be to use async/await in the method, but unfortunately, this method is being called in the constructor, so running an async method isn't recommended. I also want to note that it does catch the exception if we are not adding a custom scoped AuthenticationStateProvider to the service model and stick with the default one. Essentially, I see 2 issues to solve here:
|
I don't think this is a CSLA issue, so I'm moving this to a discussion instead of an issue. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
@rockfordlhotka Upon further research, I think the errors are related to the new StateManager using TaskCompletionSource. A google search turned up this info:
I'm not sure how to troubleshoot this further, since I'm not that familiar with this new StateManager. Any guidance is appreciated.
Originally posted by @mtavares628 in #3647 (reply in thread)
The text was updated successfully, but these errors were encountered: