Моя настройка:
- ASP.NET 4.5 web api (на Azure), сохраняющий данные в SQL db (также на Azure)
- Веб-интерфейс AngularJS (другой веб-сайт Azure)
Когда пользователь сначала регистрируется, я показываю им "вводное начало". Вступление должно запускаться только один раз - я регистрирую временную метку даты запуска ввода в качестве настраиваемого поля в пользовательской таблице ASP.NET.
Представьте себе мое удивление, когда я вхожу в систему (как пользователь) и вижу вступление TWICE.
Передняя часть AngularJS правильно отправляет сообщение "intro view" на ASP.NET api, и api отвечает сообщением об успешном завершении. Однако, когда я смотрю на необработанные данные в db, метка времени определенно НЕ обновляется. Следовательно, пользователь увидит ввод еще раз (в какой момент метка времени записывается в db должным образом).
У меня дерьмовое обходное решение. После того как клиент запрашивает токен маркера OAuth с моего сервера, клиент затем запрашивает информацию пользователя (чтобы решить, показывать или не показывать тур). Ожидание 100 мс, а затем отправка сообщения "Просмотр тура" обратно на сервер маскирует проблему.
Я не видел ЛЮБЫХ других проблем хранения данных в любой момент. Поскольку наш db находится на Azure, я не могу подключить Profiler, и встроенный аудит не дает мне никаких подсказок.
Есть ли что-то о запросе маркера, который оставляет ASP.NET-идентификатор в смешном состоянии? И требуется короткое ожидание, прежде чем вы сможете написать в таблицу? Являются ли настраиваемые поля, которые расширяют базовую настройку Identity, подверженной таким проблемам? Может ли UserManager делать что-то странное в своем черном ящике?
Есть ли у кого-нибудь предложения по продолжению отладки этой проблемы? Или когда-либо слышал о чем-то подобном?
Вот соответствующий код, который должен обновлять временную метку "просмотр тура" в db:
[HttpPost, Route("UserInfo")]
public async Task<IHttpActionResult> UpdateUserInfo(UpdateBindingModel model)
{
var currentUser = UserManager.FindById(User.Identity.GetUserId());
if (model.FirstName != null)
{
currentUser.FirstName = model.FirstName;
}
if (model.LastName != null)
{
currentUser.LastName = model.LastName;
}
if (model.SetIntroViewCompleteDate)
{
currentUser.IntroViewCompleteDate = DateTime.UtcNow;
}
if (model.SetIntroViewLaunchDate)
{
currentUser.IntroViewLaunchDate = DateTime.UtcNow;
}
if (model.SetTipTourCompleteDate)
{
currentUser.TipTourCompleteDate = DateTime.UtcNow;
}
if (model.SetTipTourLaunchDate)
{
currentUser.TipTourLaunchDate = DateTime.UtcNow;
}
IdentityResult result = await UserManager.UpdateAsync(currentUser);
if (result.Succeeded)
{
var data = new UserInfoViewModel
{
FirstName = currentUser.FirstName,
LastName = currentUser.LastName,
IntroViewLaunchDate = currentUser.IntroViewLaunchDate
};
return Ok(data);
}
return InternalServerError();
}
ОБНОВЛЕНИЕ ********* 4/18
Я также попытался полностью отойти от материалов UserManager. Я пробовал следующие изменения (вытаскивание пользовательских данных из таблицы, как я хотел бы получить доступ к любым другим данным), но он по-прежнему ведет себя одинаково. Я начинаю думать, что размещение пользовательских полей в объекте ApplicationUser - плохая идея...
Новое извлечение и сохранение db выглядит следующим образом:
ApplicationDbContext newContext = new ApplicationDbContext();
var currentUser = await (from c in newContext.Users
where c.Email == User.Identity.Name
select c).SingleOrDefaultAsync();
//update some values
await newContext.SaveChangesAsync();