Вы можете использовать фильтр , в частности, фильтр действий, который может:
- Выполнять код непосредственно перед и после вызова метода действия.
- Может изменить аргументы, переданные в действие.
- Может изменить результат, возвращенный из действия.
- Не поддерживаются в Razor Pages.
Пример
public class MySampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Do something before the action executes.
MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Do something after the action executes.
MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
}
}
Здесь вы можете подготовить сервис с областью действия, загрузить пользователя на основе сервиса и затем использовать его в любом сервисе, для которого требуются эти данные.
Даже без фильтра вы можете просто создайте UserService с ограниченным временем жизни, загрузите туда пользователя и используйте его где угодно в ваших сервисах.
В нашей системе мы делаем что-то похожее:
Сервис для загрузки данных сеанса:
public class ClientTokenService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ClientTokenService(
IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public Profile LoadProfile()
{
if (_httpContextAccessor.HttpContext.User == null)
{
throw new Exception("No user claims found to load Profile");
}
var user = _httpContextAccessor.HttpContext.User;
var numberType = (NumberType)int.Parse(user.FindFirst("numberType").Value);
var profileType = (PackagePlan)int.Parse(user.FindFirst("profileType").Value);
var lineOfBusiness = (LineOfBusiness)int.Parse(user.FindFirst("lineOfBusiness").Value);
// More stuff
// Prepare the profile data
return new Profile(
user.FindFirst("number").Value,
user.FindFirst("contractId").Value,
numberType,
profileType,
user.FindFirst("cc")?.Value,
user.FindFirst("app").Value,
user.FindFirst("clickId")?.Value,
user.FindFirst("wifi") != null,
lineOfBusiness
);
}
}
Этот сервис может быть временным, а затем сервисом с областью действия, который сохраняет данные
public class ClientSessionContext
{
public Profile Profile { get; }
public ClientSessionContext(
ClientTokenService sessionService)
{
Profile = sessionService.LoadProfile();
}
}
Объявить этот сервис как область действия, поэтому этот класс инициализируется только один раз за запрос
* * Св тысячи тридцать-одна atup.cs
services.AddScoped<ClientSessionContext>();
Затем просто внедрите этот сервис в любое место, где вам нужен доступ к данным пользователя.