我正在尝试在服务器上托管Blazor应用程序。 我花了整个夏天的时间,每次我在新设备上打开网站时都没有意识到它不会创建一个从零开始的新会话,但是会一直停留在我离开的地方。最糟糕的部分是背后有一个登录系统,所以我现在觉得很笨。
我真的需要如何解决这个“不少”问题的大提示。 有没有一种方法可以使服务器在每次有人打开网站时创建新会话(而不会使其对其他用户失去作用)?
该解决方案应改为使用客户端模板,但性能确实会降低。
更新: 帐户“用户密码”为: -用户用户 -测试测试
Download project sample (requires Net Core 3.0)
[解决方案] ,它为我的问题找到了解决方法。
您还必须在ConfigureServices
的Startup.cs中添加services.AddScoped<Storage>();
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<Storage>();
}
答案 0 :(得分:1)
每次我在新设备上打开网站时,它都不会创建从零重新开始的新会话,但是会继续保留我离开的位置。
我检出您的代码,发现您正在使用Singleton Pattern初始化Storage
。如果我正确理解,则此Storage
单例实例将在不同用户之间(以及在不同设备上)共享。由于此实例将用于呈现Main.razor
页面,因此您现在遇到的并发问题。
要解决该问题,应将Storage实例限制在某些特定的连接范围内。使用Blazor Server Side时,可以将存储注册为 Scoped Service
:
在Blazor Server应用程序中,作用域内的服务注册作用域中的连接。因此,即使当前意图是在浏览器中运行客户端,也应该优先使用范围服务,而不是应该对当前用户进行范围限制的服务。
首先,删除静态单例实例:
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;} }
将此类注册为范围服务:
services.AddScoped<Storage>();
然后将此服务注入您的Login.razor
和Main.razor
中:
@inject project.Storage Storage
最后,您需要将所有Storage.GetInstance().
更改为Storage.
:
Storage.list = Order;
...
Storage.password = password;
我注意到您也在使用Singleton Pattern创建Importer
/ Additional
实例。我建议您应该重构它们以类似方式使用服务注入。