user13714356
user13714356

Reputation: 171

Blazor Server - Session advice

I have a Blazor Server app. I would like store some data in a Session. I am trying to create a Session Helper class where I store the Session Names as Enums so they are always strongly typed. Also in this class I would like to put the Get and Set. So I dont need to do lots of Injecting everywhere. The session Value could be a string, object. list etc... I started to create below class but came across a few issues:

  1. Can I create the below into static methods so I dont have new the SessionManager object everytime
  2. How do I get the Get to return any type of object. I think I need to make it generic some how.

Any help would be much appreciated

TIA

    using Microsoft.AspNetCore.Components;
    using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
    using System.Threading.Tasks;
    
    namespace Core
    {
        public class SessionManager
        {
            [Inject] ProtectedSessionStorage storage { get; set; }
    
            public enum eSessionNames
            {
                UserName,
                UserRow
            }
    
            public async Task SetSession(eSessionNames SessionName, object Value)
            {
                await storage.SetAsync(SessionName.ToString(), Value);
            }
    
            public async Task<T> GetSession(eSessionNames SessionName)
            {
                return await storage.GetAsync<T>(SessionName.ToString());
            }
        }
    }


MY DAL trying to use your method

        public async static Task<Models.myModel> GetUserFromProtectedBrowserStorageAsync(string UserNetworkID)
        {
            using (var connection = new SqlConnection(Core.ConnectionStringManager.GetConnectionString()))
            {
                await connection.OpenAsync();

                MyBlogProtectedBrowserStorage pbs = new();  //I get an error on this line as im not sure how to new the object

                Models.myModel output = await pbs.GetAsync<Models.myModel>("UserRow");

                if (output == null)
                {
                    var values = new { UserNetworkID };

                    output await connection.QuerySingleAsync<CsatUserModel>("SELECT * FROM tblUsers WHERE NetworkID = @UserNetworkID", values, commandType: CommandType.Text);

                    pbs.SetAsync<Models.myModel>("UserRow", output);

                    return output;
                }
                else
                {
                    return output;
                }
            }
        }

Upvotes: 0

Views: 1519

Answers (2)

Mayur Ekbote
Mayur Ekbote

Reputation: 2080

You don't need to use protected session storage in Blazor server since Blazor sever can maintain the app session state on the server side.

For your purpose, I suggest you use IMemoryCache. It's simple to use and works with all types of classes.

https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-6.0

Upvotes: 1

Jimmy Engtr&#246;m
Jimmy Engtr&#246;m

Reputation: 2008

The concept of session doesn't really exist in Blazor Server at least not in the traditional meaning. You can use ProtectedSessionStorage ad you do or you can use dependency injection and inject a class that is scoped. This will make the class accessible while you have a connection (Circuit), if the connection fails for some reason the scoped class will disappear as well.

To answer your questions:

  1. Don't use static methods inject the Sessionmanager into your component and/or classes instead. This makes it easier to see dependencies and write tests.
  2. Here is an example:
public class MyBlogProtectedBrowserStorage
{
    ProtectedSessionStorage storage { get; set; }
    public MyBlogProtectedBrowserStorage(ProtectedSessionStorage storage)
    {
        this.storage = storage;
    }

    public async Task DeleteAsync(string key)
    {
        await storage.DeleteAsync(key);
    }

    public async Task<T?> GetAsync<T>(string key)
    {
        var value = await storage.GetAsync<T>(key);
        if (value.Success)
        {
            return value.Value;
        }
        else
        {
            return default(T);
        }
    }

    public async Task SetAsync(string key, object value)
    {
        await storage.SetAsync(key, value);
    }
}

Upvotes: 1

Related Questions