You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC中Edit页面RedirectToAction跳转至登录页问题排查

ASP.NET MVC Edit操作后RedirectToAction跳转到登录页问题排查与解决

问题现象

在ASP.NET MVC应用中,Edit页面执行POST提交后,调用RedirectToAction("Index")未跳转到Index页面,反而重定向至登录页;重新登录后可正常跳转。登录时生成认证Cookie,点击保存按钮前Cookie无变化,触发登录提示并重新登录后Cookie值才更新,且未主动修改过Cookie。

相关代码

Edit POST Action(含角色验证版本)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(SampleVM samplevm)
{
    if (!IsUserInAuthorizedRole())
    {
        return View("~/Views/Shared/Unauthorized.cshtml");
    }

    if (ModelState.IsValid)
    {
        samplevm.UserId = User.Identity.Name;
        Sample sample = PopulateSample(samplevm);
        db.Entry(sample).State = EntityState.Modified;
        db.SaveChanges();

        TempData["Message"] = "Sample has been updated.";

        return RedirectToAction("Index");
    }
    
    return View(samplevm);
}

其他相关Action

// POST Create
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult SaveSamples(SampleVM samplevm)
{
    bool status = false;

    if (ModelState.IsValid)
    {
        var lotExists = SampleExists(samplevm.LotId);

        if(lotExists)
        {
            return Json(new { 
                success = false
                , status = status
                , responseText = "LotId " + samplevm.LotId + " already exists." 
            }, JsonRequestBehavior.AllowGet);
        }

        samplevm.UserId = User.Identity.Name;

        Sample sample = PopulateSample(samplevm);

        db.Samples.Add(sample);
        db.SaveChanges();
        int sampleId = sample.SampleId;

        status = true;

        return Json(new { 
            success = true
            , redirectUrl = Url.Action("Index", "Samples")
            , status = status, responseText = "Sample has been saved" 
        }, JsonRequestBehavior.AllowGet);
    }

    return new JsonResult { Data = new { status = status } };
}

// POST Edit(无角色验证版本)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(SampleVM samplevm)
{
    if (ModelState.IsValid)
    {
        samplevm.UserId = User.Identity.Name;
        Sample sample = PopulateSample(samplevm);
        db.Entry(sample).State = EntityState.Modified;
        db.SaveChanges();

        TempData["Message"] = "Sample has been updated.";

        return RedirectToAction("Index");
    }
    
    return View(samplevm);
}

排查与解决方向

  • 优先验证身份有效性而非仅角色
    检查IsUserInAuthorizedRole()方法,是否只验证角色而未先确认用户是否已认证。如果会话超时但User.Identity.IsAuthenticated仍为true(Cookie已失效但客户端未更新),会导致执行完数据库操作后,重定向时才触发认证检查。建议在Action开头先判断:

    if (!User.Identity.IsAuthenticated)
    {
        return RedirectToAction("Login", "Account");
    }
    if (!IsUserInAuthorizedRole())
    {
        return View("~/Views/Shared/Unauthorized.cshtml");
    }
    
  • 检查Forms认证Cookie配置
    打开Web.config,确认Forms认证的timeout和slidingExpiration设置:

    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" slidingExpiration="true" />
    </authentication>
    

    slidingExpiration="true"会在每次活跃请求时延长Cookie有效期,避免编辑操作过程中超时;确保timeout值足够覆盖正常操作时长。

  • 同步Session与认证超时时间
    TempData依赖Session,如果Session超时时间短于Forms认证Cookie超时,会导致重定向时Session失效,间接触发认证检查。检查Session配置:

    <sessionState mode="InProc" timeout="2880" />
    

    让Session超时时间与Forms认证保持一致。

  • 排查Cookie是否被意外修改
    用浏览器F12开发者工具,查看Edit请求的Request Headers里的Cookie值,以及响应的Response Headers是否有Set-Cookie头。如果服务器在响应中发送了新的认证Cookie,说明有逻辑在修改Cookie,需要排查全局过滤器、安全组件或其他请求处理代码。

  • 验证Anti-Forgery Token有效性
    Anti-Forgery Token与当前认证会话绑定,如果Cookie过期,Token会失效。可以在Edit页面加载时,确保Token是基于有效会话生成的;也可以添加全局认证过滤器,提前拦截未认证请求,避免执行完业务逻辑后才重定向登录。

内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:05:05