Elio
Elio

Reputation: 83

NET Core Server Side multiple session Blazor

I'm trying to host my Blazor application on my server. I spent all the summer on it and I just realized every time I open my website on new device it doesn't create a new session restarting from zero, but continues where I left it. The worst part is there is a login system behind it, so I feel super dumb at the moment.

I really need a big hint on how to fix this "not little" issue. Is there a way to make server create new session every time someone open the website (without making it loose to other users)?

The solution should be use a Client Template instead, but the performance are really to slow.

UPDATE: Accounts "user password" are: - user user - test test

Download project sample (requires Net Core 3.0)

[SOLUTION] itminus found the solution to my issue.

You have also to add in ConfigureServices in Startup.cs this services.AddScoped<Storage>();

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddScoped<Storage>();
        }

Upvotes: 4

Views: 4277

Answers (1)

itminus
itminus

Reputation: 25380

every time I open my website on new device it doesn't create a new session restarting from zero, but continues where I left it.

I checkout your code and find that you're using Singleton Pattern to initialize the Storage. If I understand it correctly, this Storage singleton instance will be shared across different users (also across different devices). As this instance will be used to render the Main.razor page, there will be concurrency problems that you're experiencing now .

To fix that issue, the Storage instance should be limited within some specific connection. As you're using Blazor Server Side, you could register the Storage as a Scoped Service:

In Blazor Server apps, a scoped service registration is scoped to the connection. For this reason, using scoped services is preferred for services that should be scoped to the current user, even if the current intent is to run client-side in the browser.

Firstly, remove the static singleton instance :

public class Storage
{
    private static Storage instance;
    private Storage()                         
    {                                         
    }                                         
    public static Storage GetInstance()       
    {                                         
         if (Storage.instance == null)        
             Storage.instance = new Storage();
         return Storage.instance;             
     }                                        

    public List<Items>list {get;set;} = new List<Items>();
    public string password {get;set;}

}

Register this Class as a scoped service:

services.AddScoped<Storage>();

And then inject this service in your Login.razor and Main.razor :

@inject project.Storage Storage

Finally, you need change all the Storage.GetInstance(). to Storage.:

    Storage.list = Order;
    ...
    Storage.password = password;

I notice that you're also creating the Importer/Additional instance using the Singleton Pattern. I would suggest you should refactor them to use Service Injection in a similar way.

Upvotes: 5

Related Questions