我以前从未见过这种情况而且很难过。我有以下控制器序列:
/// <summary>
/// Helper method to store offerId to TempData
/// </summary>
/// <param name="offerId"></param>
private void StoreOfferInTempData(string offerId)
{
if (TempData.ContainsKey(SelectedOfferKey))
TempData.Remove(SelectedOfferKey);
TempData.Add(SelectedOfferKey, offerId);
}
[HttpPost]
[AllowAnonymous]
public virtual ActionResult Step1(MyViewModel model)
{
if (ModelState.IsValid)
{
StoreOfferInTempData(model.SelectedOfferId);
return RedirectToAction(MVC.Subscription.Register());
}
MySecondViewModel model2 = new MySecondViewModel { OfferId = model.SelectedOfferId };
return View(model2);
}
[HttpGet]
[AllowAnonymous]
public virtual ActionResult Register()
{
string offerId = TempData[SelectedOfferKey] as string; //we get a valid value here
... error handling content elided ...
RegisterViewModel model = new RegisterViewModel { OfferId = offerId };
return View(model);
}
[HttpPost]
[AllowAnonymous]
public virtual ActionResult Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
CreateCustomerResult result = CustomerService.CreateAccount(model.Email, model.NewPassword);
if (result.Success)
{
... content elided; storing customer to Session ...
MyMembershipProvider.PersistUserCookie(result.Principal, true);
//need to store our selected OfferId again for use by the next step
StoreOfferInTempData(model.OfferId);
return RedirectToAction(MVC.Subscription.Payment());
}
model.ErrorMessage = result.ErrorMessage;
}
return View(model);
}
[HttpGet]
public ActionResult Payment()
{
string offerId = TempData[SelectedOfferKey] as string; //this is null???
... content elided ...
return View(model);
}
TempData的第一轮存储行为符合预期。该值存在于随后的HttpGet方法中,并标记为删除,以便在我再次添加它时不再存在。但是,在第三个HttpGet方法上,它返回null。
我尝试过每轮使用不同的密钥而不做任何更改。我可以向你保证,除了显示的那些,我在任何时候都在检查TempData,所以我认为没有办法以某种方式将值标记为删除。此外,它在Payment方法中是否有[AllowAnonymous]属性失败(因此不是由于任何http到https开关或类似的东西。
似乎它必须是非常简单的东西,但我的搜索结果一无所获。非常感谢任何帮助。
更新:在进一步检查时,出于某种原因,似乎我的整个背景都在这一步骤中被冲洗了。我们在控制器中使用IoC,但没有IoC实例化的项目。神秘感加深了。
答案 0 :(得分:3)
TempData
的生命周期只有在它被读回或下一个请求被处理(永远是第一个)之前。如果您要处理两(或三)个请求,则不应依赖TempData
。而是使用会话或数据库。
TempData
的目的是在请求之前切换信息,直到您清除它为止(这就是会话的目的)。
答案 1 :(得分:1)
啊哈!嗯,这很模糊,我希望它可以帮助别人。事实证明,我忘记在创建Payment()动作后运行我的T4MVC.tt文件,因此采用MVC.Subscription.Payment()动作的RedirectToAction没有正确实例化控制器。我不清楚这里的所有潜在魔法,但如果你碰到这个并使用T4MVC.tt,请确保你运行它!
对于为什么会这样做的评论是受欢迎的。
答案 2 :(得分:0)
使用TempData.Keep("key")
保留多个回发之间的值