Есть проект WebForms (legacy) + ASP.NET MVC + SimpleInjector
public abstract class CustomBaseController : Controller
{
protected User user;
protected IAppDbContext repo;
public CustomBaseController(User user, IAppDbContext repo)
{
this.user = user;
this.repo = repo;
}
}
// my controller
[MyCustomAuthorize]
public class MyCustomController : CustomBaseController
{
public MyCustomController(User user, IAppDbContext repo) : base(user, repo)
{
}
[HttpPost]
public ActionResult PostMethod()
{
try
{
// Какое-то обращение к полю user
// Получаю NullReferenceException
user.Name = "NewUserName";
}
catch (Exception ex)
{
// логирование
}
}
}
// user entity
public class User
{
public Guid Id { get; protected set; }
public string Email { get; protected set; }
public string DisplayName { get; protected set; }
public string FirstName { get; protected set; }
public string LastName { get; protected set; }
// and other properties
}
// Инициализация DI
private static void InitializeContainer()
{
var container = new Container();
container.Register<IUserSessionManagement, UserSessionManagement >(Lifestyle.Scoped);
container.Register<User>(() => container.GetInstance<UserSessionManagement>().UserSession, Lifestyle.Scoped);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
// Wrapper for User
public class UserSessionManagement : IUserSessionManagement
{
public User UserSession { get; }
public UserSessionManagement(IAppDbContext repo)
{
UserSession = (HttpContext.Current.Session[SESSION_AUTHENTICATED_USER] as User) ?? new User(Guid.Empty, null, null);
}
}
user
и везде только запрашиваю, а пишут только 1 раз в конструкторе CustomBaseController
. 1) Пробовал подождать пока сессия экспарируется.
2) Пробовал залогиниться. Открыть еще одну вкладку в браузере. Выйти из первой. Сделать запрос со второй (ничего).
3) Сымитировать долгий запрос через thread sleep (но это фигня по-моему)
NOTE: Спрашивал на англоязычном SO, но мой английский слаб и у меня не получилось с первого раза объяснить проблему, когда к ней еще был интерес.
UPD:
Текст ошибки получается таким, где UserID пустой, потому что там через null propagation сделано. Соответственно user был null.
An exception occured. Error id: c90dfe71-c608-4412-9805-c1cb9bf92bc6. UserID:;
Полное содержание вызываемого метода.
[HttpPost]
public ActionResult PostMethod()
{
try
{
var provider = repo.GetProviderInfo(user.Id);
return Json(provider);
}
catch (Exception ex)
{
var internalErrorId = Guid.NewGuid();
MSSQLLogger.Instance.GetLogger(MethodBase.GetCurrentMethod())
.Error($"An exception occured. Error id: {internalErrorId}. UserID:{user?.Id};", ex);
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, $"Error id: {internalErrorId}");
}
}
В общем, что бы я посоветовал:
// Инициализация DI
private static void InitializeContainer()
{
var container = new Container();
container.Register<IUserSessionManagement, UserSessionManagement>(Lifestyle.Scoped);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
Базовый класс
public abstract class CustomBaseController : Controller
{
protected IUserSessionManagement SessionManagement;
protected IAppDbContext repo;
public CustomBaseController(IUserSessionManagement sessionManagement, IAppDbContext repo)
{
this.SessionManagement = sessionManagement;
this.repo = repo;
}
}
Котроллер
// my controller
[MyCustomAuthorize]
public class MyCustomController : CustomBaseController
{
public MyCustomController(IUserSessionManagement sessionManagement, IAppDbContext repo) : base(sessionManagement, repo)
{
}
[HttpPost]
public ActionResult PostMethod()
{
try
{
var user = SessionManagement.UserSession;
// Какое-то обращение к полю user
// Получаю NullReferenceException
user.Name = "NewUserName";
}
catch (Exception ex)
{
// логирование
}
}
}
Проблема оказалась в следующем: так как все хранилось в сессии и после перезагрузки IIS (или обновления web.config
) там ничего не лежит.
В сессию информация о юзере попадает после того как происходит обращение к любой странице написанной на WebForm, то бишь отрабатывает логика Admin.Master
, но т.к. присутствует лапша из разных технологий, то при прямом обращении через ajax запрос логика из Admin.Master
не отрабатывала. Проще говоря забыли добавить это в кастомные атрибуты авторизации.
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Как реализовать превью чужих окон в своём окне? Аналогично нажатию alt+tab
Не понимаю, постоянно ловлю ошибки например