Session-based singleton service in ASP.NET Core MVC

huangapple go评论107阅读模式
英文:

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&lt;string, ClientConnector&gt; _clients;
  
  public ClientConnectors()
  {
    _clients = new Dictionary&lt;string, ClientConnector&gt;();
  }

  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&lt;HomeController&gt; _logger;
        protected ClientConnector _client;
    private ClientConnectors _clients;
    private IHttpContextAccessor _httpContextAccessor;

        public BaseController(ILogger&lt;HomeController&gt; 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(&quot;MoxSessionId&quot;);
        
        if (string.IsNullOrEmpty(returnValue))
        {
            returnValue = Guid.NewGuid().ToString();
            _httpContextAccessor.HttpContext.Session.SetString(&quot;MoxSessionId&quot;, returnValue);
        }
        
        return returnValue;
    }
    }

HomeController.cs

public class HomeController : BaseController
    {
        public HomeController(ILogger&lt;HomeController&gt; logger, ClientConnectors clients, IHttpContextAccessor hca) : base(logger, clients, hca) { }

        public IActionResult Index()
        {
            var model = new HomeViewModel(_client.IncreaseAndDisplayCounter());
            return View(model);
        }
    }

huangapple
  • 本文由 发表于 2023年4月17日 15:54:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76032854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定