为什么 TempData[] 在 MVC 中的 RedirectToAction 之后为 NULL

Why is TempData[] NULL after RedirectToAction in MVC

问题:我在 Post 操作中设置了 TempData,然后重定向到我的索引操作。在我设置后,TempData 在 post 中不为 NULL,但在 Index 操作中为 NULL。

我一直在搜索线程以找到这个问题的答案,我所看到的一切都表明以下内容应该有效,但遗憾的是,它没有。

谁能看出这里出了什么问题?

[HttpGet]
        public async Task<IActionResult> Index()
        {
            //var lCARContext = _context.TblRules.Include(t => t.Agency).Include(t => t.Department);
            //return View(await lCARContext.ToListAsync());

            var rulevm = new RulesViewModel();
> TempData is NULL at this point.
            var actionConfirmation = TempData["ActionConfirmation"];
            TempData["ActionConfirmation"] = actionConfirmation;
            return View(rulevm);
        }

[HttpPost]
public async Task<IActionResult> Edit(string id, 
            [Bind("...")]
            TblRules tblRules, string NewProposedRuleNo)
        {
            if (id != tblRules.ProposedRuleNo)
            {
                return NotFound();
            }

            if (!tblRules.AgencyId.HasValue & !tblRules.DepartmentId.HasValue)
            {

                ModelState.AddModelError(string.Empty, "Select an Agency and/or Department for this rule.");
                // set the property level messages
                ModelState["AgencyId"].Errors.Add("Need either an Agency or Department specified.");
                ModelState["DepartmentId"].Errors.Add("Need either an Agency or Department specified.");
            }

            if (ModelState.IsValid)
            {
                try
                {
                    // first save any changes other than the rule number that the user
                    // has made.
                    _context.Update(tblRules);
                    await _context.SaveChangesAsync();

                    // Now if user changed the proposed rule number change it.
                    // Needs to be done outside of EF since EF does not support changing the PK.
                    if (NewProposedRuleNo != null)
                    {
                        _context.ChangeProposedRuleNumber(tblRules.ProposedRuleNo, NewProposedRuleNo);
                    }
                    // Return results of the action
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    if (!TblRulesExists(tblRules.ProposedRuleNo))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                TempData["ActionConfirmation"] = "Processing successful.";
> TempData is Not NULL at this point.
                return RedirectToAction("Index");
                //return RedirectToAction(nameof(Index));
            }
            // following executed if model is not valid
            ViewData["AgencyId"] = new SelectList(_context.TblAgencies.Where(wh => wh.AgencyOrBoard != null).OrderBy(ob => ob.AgencyOrBoard), "AgencyId", "AgencyOrBoard", tblRules.AgencyId);
            ViewData["DepartmentId"] = new SelectList(_context.TblDepartments.Where(wh => wh.DeptOrDivision != null).OrderBy(ob => ob.DeptOrDivision), "DepartmentId", "DeptOrDivision", tblRules.DepartmentId);
            ViewData["RuleType"] = new SelectList(_context.TlkpRuleTypes.OrderBy(ob => ob.RuleType), "RuleType", "RuleType", tblRules.RuleType);
            ViewData["Attorneys"] = new SelectList(_context.TblAttorneys.OrderBy(ob => ob.AttorneyName), "AttorneyName", "AttorneyName", null);
            ViewData["CurrentAttorneys"] = new SelectList(tblRules.TblReceivingAttorneys.OrderBy(ob => ob.AttorneyName), "AttorneyName", "AttorneyName", null);
            ViewData["CommitteesOfJurisdiction"] = new SelectList(_context.TblCommittees.OrderBy(ob => ob.CommitteName), "CommitteName", "CommitteName", null);
            ViewData["CurrentCommitteesOfJurisdiction"] = new SelectList(tblRules.TblCommitteesOfJurisdiction.OrderBy(ob => ob.CommitteName), "CommitteName", "CommitteName", null);
            ViewData["Actions"] = new SelectList(_context.TlkpActionsTaken.OrderBy(ob => ob.ActionDescription), "ActionDescription", "ActionDescription", null);
            ViewData["CurrentActions"] = new SelectList(tblRules.TblActions.OrderBy(ob => ob.ActionDescription), "ActionId", "ActionDescription", null);
            // Return the rules edit view model.
            var vm = tblRules.ToCreateRulesEditViewModel();
            // Return results of the action
            TempData["ActionConfirmation"] = "Validations failed.";
> TempData is Not NULL at this point AND is displayed on the view
            vm.AgencyContact = ViewModelExtensionMethods.FormatAgencyContactInformation(tblRules.Agency, true, true);
            return View(vm);
        }

_Layout.cshtml 显示 TempData on Validation 错误但不显示 Success 值

<div>
    @if (TempData["ActionConfirmation"] != null)
    {
        <p>@TempData["ActionConfirmation"]</p>
    }
    </div>

Index.cshtml 显示验证错误但不成功的 TempData

<div>
    @if (TempData["ActionConfirmation"] != null)
    {
        <p>@TempData["ActionConfirmation"]</p>
    }
</div>

我找到了解决方案。显然在 Startup.Configure 中我需要在 app.UseMVC() 之后有 app.UserCookiePolicy()。进行此更改允许 Tempdata 在重定向过程中保持不变。

This page 为我提供了解决问题的提示。我依赖于 hmdhasani 的原始信息,而不是下面的例子,它仍然有 app.UserCookiePolicy 第一。

        app.UseMvc(routes =>
        {
            //routes.MapRoute(
            routes.MapRoute(
                name: "default",
                template: "{controller=TblRules}/{action=Index}/{id?}");
        });

        app.UseCookiePolicy();

希望这 post 对其他人有所帮助。