Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

SignalR hub in Library Project always have context null

$
0
0

I followed the below solution and moved code into library project. It works fine if I have hub connection in Blazor Server project but doesn't work when moved to library project:

Adding cookies to SignalR Core requests

I have below service in the Library Razor project, that hold implementation of hub connection setup and is shared among two Blazor server apps:

public class UserHubService : IAsyncDisposable{  private HubConnection? _hubConnection;  public async Task<bool> InitializeHubAsync(string baseUrl, string hubPath, string subscribeToGroup, Guid? siteId, string userName)  {    UserName = userName;    var uri = new Uri(new Uri(baseUrl), hubPath);    //_hubConnection = new HubConnectionBuilder()    //    .WithUrl(new Uri(new Uri(baseUrl), hubPath))    //    .Build();    _hubConnection = new HubConnectionBuilder()    .WithUrl(uri, opti =>    {        if (_httpContextAccessor.HttpContext != null)            foreach (var c in _httpContextAccessor.HttpContext.Request.Cookies)            {                opti.Cookies.Add(new Cookie(c.Key, c.Value)                {                    Domain = uri.Host, // Set the domain of the cookie                    Path = "/" // Set the path of the cookie                });            }    })    .Build();    _hubConnection.On<Guid?, ProductModel, string>(SignalR_Method.TouchProductReceiveNotification, async (siteID, product, messageType) =>    {        if (_subscribedMessageTypes.Contains(messageType))        {            await HandleNotificationAsync(siteID, product, messageType);        }    });    try    {        await _hubConnection.StartAsync();        await _hubConnection.InvokeAsync(subscribeToGroup, siteId);        return true;    }    catch (Exception ex)    {        return false;        // Handle exception (e.g., log it)    }  }}

The above service is injected in page and called from Server app:

await ProductNotificationHubService.InitializeHubAsync(baseUrl, hubPath, SignalR_Method.SubscribeToTouchSiteGroup, Site.Site_ID, _userInfo.UserName)

Below is the hub again in Library razor project:

[Authorize]public class NotificationHub : Hub{    private static readonly ConcurrentDictionary<string, List<string>> UserConnections = new();    [Authorize]    public override Task OnConnectedAsync()    {        var userEmail = Context.User?.FindFirst(ClaimTypes.Email)?.Value;        //var userName = Context.User?.Identity?.Name; // Assuming the username is stored in the Name claim        if (!string.IsNullOrEmpty(userEmail))        {            UserConnections.AddOrUpdate(               userEmail,               new List<string> { Context.ConnectionId }, // Add a new list with the current connection ID               (key, existingConnections) =>               {                   if (!existingConnections.Contains(Context.ConnectionId))                   {                       existingConnections.Add(Context.ConnectionId); // Add the connection ID to the existing list                   }                   return existingConnections;               });        }        return base.OnConnectedAsync();    }    [Authorize]    public override Task OnDisconnectedAsync(Exception exception)    {        var userEmail = Context.User?.FindFirst(ClaimTypes.Email)?.Value;        var connectionID = Context.ConnectionId;        if (!string.IsNullOrEmpty(userEmail))        {            if (UserConnections.TryGetValue(userEmail, out var connections))            {                // Remove the specific connection ID                connections.Remove(Context.ConnectionId);                // If no more connections exist for this user, remove the user entry from the dictionary                if (connections.Count == 0)                {                    UserConnections.TryRemove(userEmail, out _);                }            }        }        return base.OnDisconnectedAsync(exception);    }}

I have confirmed that cookies are being set properly:

_hubConnection = new HubConnectionBuilder().WithUrl(uri, opti =>{    if (_httpContextAccessor.HttpContext != null)        foreach (var c in _httpContextAccessor.HttpContext.Request.Cookies)        {            opti.Cookies.Add(new Cookie(c.Key, c.Value)            {                Domain = uri.Host, // Set the domain of the cookie                Path = "/" // Set the path of the cookie            });        }}).Build();

In the program.cs file:

builder.Services.AddAuthentication(options =>{    options.DefaultScheme = IdentityConstants.ApplicationScheme;    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;    options.RequireAuthenticatedSignIn = true;}).AddCookie(options =>{    options.LoginPath = "/Account/Login/";    options.LogoutPath = "/Account/Logout/";    options.AccessDeniedPath = "/Account/AccessDenied";    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;    options.Cookie.HttpOnly = true;    options.SlidingExpiration = true;    options.ExpireTimeSpan = TimeSpan.FromSeconds(30);}).AddIdentityCookies();app.UseAuthentication();app.UseAuthorization();

The connection is successful and connected however, the issue I am having is that userEmail in below line is always null:

var userEmail = Context.User?.FindFirst(ClaimTypes.Email)?.Value;

Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>