英文:
Session-based singleton service in ASP.NET Core MVC
问题
我正在构建一个用于我的应用程序的ASP.NET MVC页面作为Web客户端。我的应用程序提供了一个名为"ClientConnector"的组件,用于处理所有与服务器的请求以及处理身份验证...
对于WPF客户端,没有问题 - 当我启动客户端时,我创建一个新的ClientConnector实例,一切都正常。
但是在使用Web客户端时,我需要为每个浏览器会话创建一个实例 - 但在会话内,实例需要保持一致。
我找到了一些关于会话处理和会话变量的信息 - 但所有示例都只使用简单值而不是复杂对象。
是否可以提供一个简单(完整的)示例来实现这个想法?
目前,我在startup.cs的"ConfigureServices"方法中添加了"new"命令。
services.AddSingleton(new ClientConnector());
但是当然,这种方式会使ClientConnector在整个应用程序中保持持久性 - 与浏览器会话无关。
谢谢和问候
Markus
英文:
I'm building a ASP.NET MVC page as a webclient for my own application.
My application provides a "ClientConnector" handling all requests to the server and handling authentication ...
For the WPF client there is no problem - I create a new instance of the ClientConnector when I start the client and all is fine.
But when using the webclient I need to create the instance for every browser session - but within the session the instance needs to be consistent.
I found a few information about session handling and session variables - but all the examples only work with simple values but not with complex objects.
May anybody provide a simple (and complete) example for implementing this idea?
Currently I added the "new"-command within the "ConfigureServices" method in the startup.cs.
services.AddSingleton(new ClientConnector());
But of course this way the ClientConnector is persistent for the complete application - independent of the browser session.
Thanks and regards
Markus
答案1
得分: 0
I created a simple dictionary as the service - storing a session id and the actual client connector.
然后我在一个基础控制器类中添加了以下代码,我的实际控制器从这个基础类继承,只是为了使一切都更加清晰。
ClientConnectors.cs
public class ClientConnectors
{
private readonly Dictionary<string, ClientConnector> _clients;
public ClientConnectors()
{
_clients = new Dictionary<string, ClientConnector>();
}
public ClientConnector GetClientConnectorForSession(string sessionId)
{
if (_clients.ContainsKey(sessionId))
{
return _clients[sessionId];
}
else
{
var client = new ClientConnector();
_clients.Add(sessionId, client);
return client;
}
}
}
BaseController.cs
public class BaseController : Controller
{
protected readonly ILogger<HomeController> _logger;
protected ClientConnector _client;
private ClientConnectors _clients;
private IHttpContextAccessor _httpContextAccessor;
public BaseController(ILogger<HomeController> logger, ClientConnectors clients, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
_clients = clients;
_httpContextAccessor = httpContextAccessor;
IdentifyClientConnection();
}
private void IdentifyClientConnection()
{
_client = _clients.GetClientConnectorForSession(CreateOrGetSessionId());
}
private string CreateOrGetSessionId()
{
var returnValue = _httpContextAccessor.HttpContext.Session.GetString("MoxSessionId");
if (string.IsNullOrEmpty(returnValue))
{
returnValue = Guid.NewGuid().ToString();
_httpContextAccessor.HttpContext.Session.SetString("MoxSessionId", returnValue);
}
return returnValue;
}
}
HomeController.cs
public class HomeController : BaseController
{
public HomeController(ILogger<HomeController> logger, ClientConnectors clients, IHttpContextAccessor hca) : base(logger, clients, hca) { }
public IActionResult Index()
{
var model = new HomeViewModel(_client.IncreaseAndDisplayCounter());
return View(model);
}
}
这些是您提供的代码的翻译部分。
英文:
Thanks for the idea @Timofeus:
I created a simple dictionary as the service - storing a session id and the actual client connector.
Then I added the following code to a base controller class where my actual controller inherits from, just to make everything a little more clean.
(here all the code, if somebody comes over this post)
ClientConnectors.cs
public class ClientConnectors
{
private readonly Dictionary<string, ClientConnector> _clients;
public ClientConnectors()
{
_clients = new Dictionary<string, ClientConnector>();
}
public ClientConnector GetClientConnectorForSession(string sessionId)
{
if (_clients.ContainsKey(sessionId))
{
return _clients[sessionId];
}
else
{
var client = new ClientConnector();
_clients.Add(sessionId, client);
return client;
}
}
}
BaseController.cs
public class BaseController : Controller
{
protected readonly ILogger<HomeController> _logger;
protected ClientConnector _client;
private ClientConnectors _clients;
private IHttpContextAccessor _httpContextAccessor;
public BaseController(ILogger<HomeController> logger, ClientConnectors clients, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
_clients = clients;
_httpContextAccessor = httpContextAccessor;
IdentifyClientConnection();
}
private void IdentifyClientConnection()
{
_client = _clients.GetClientConnectorForSession(CreateOrGetSessionId());
}
private string CreateOrGetSessionId()
{
var returnValue = _httpContextAccessor.HttpContext.Session.GetString("MoxSessionId");
if (string.IsNullOrEmpty(returnValue))
{
returnValue = Guid.NewGuid().ToString();
_httpContextAccessor.HttpContext.Session.SetString("MoxSessionId", returnValue);
}
return returnValue;
}
}
HomeController.cs
public class HomeController : BaseController
{
public HomeController(ILogger<HomeController> logger, ClientConnectors clients, IHttpContextAccessor hca) : base(logger, clients, hca) { }
public IActionResult Index()
{
var model = new HomeViewModel(_client.IncreaseAndDisplayCounter());
return View(model);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论