在没有 RedirectToAction() 的 SignOut() 之后清除 Request.IsAuthenticated 值

Posted

技术标签:

【中文标题】在没有 RedirectToAction() 的 SignOut() 之后清除 Request.IsAuthenticated 值【英文标题】:Clear Request.IsAuthenticated value after SignOut() without RedirectToAction() 【发布时间】:2010-10-30 15:21:44 【问题描述】:

我正在编写一个帐户管理控制器,并且必须单独处理删除自己用户的帐户:

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(string userName, string confirmButton)

    MembershipService.DeleteUser(userName);

    if (User.Identity.Name.Equals(userName,
        StringComparison.InvariantCultureIgnoreCase))
    
        FormsAuth.SignOut();

        return View("DeleteSelf");
    
    else
        return RedirectToAction("Index");

但部分视图 LogOnUserControl.ascx 在显示 DeleteSelf 视图时仍然显示刚刚注销的用户名,因为 Request.IsAuthenticated 和 Page.User.Identity 值仍然在 FormsAuth.SignOut() 之后设置。

添加一个新动作 ShowDeleteSelfMessage 可以解决问题,但我不喜欢这个解决方案:

    ...
    
        FormsAuth.SignOut();

        return RedirectToAction("ShowDeleteSelfMessage");
    
    ...

public ActionResult ShowDeleteSelfMessage()

    return View("DeleteSelf");

还有其他想法吗?谢谢!

【问题讨论】:

【参考方案1】:

更改您的 LogOnUserControl.ascx 以处理 ViewData["UserDeleted"]:

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(string userName, string confirmButton)

    MembershipService.DeleteUser(userName);

    if (User.Identity.Name.Equals(userName,
        StringComparison.InvariantCultureIgnoreCase))
    
        FormsAuth.SignOut();

        // ***
        ViewData["UserDeleted"] = true;
        // ***

        return View("DeleteSelf");
    
    else
        return RedirectToAction("Index");

LogOnUserControl.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% if (Request.IsAuthenticated && !(ViewData["UserDeleted"] ?? false))  %>
    Welcome <b><%= html.Encode(Page.User.Identity.Name) %></b>!
    [ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]
<%  else  %> 
    [ <%= Html.ActionLink("Log On", "LogOn", "Account") %> ]
<%  %>

【讨论】:

【参考方案2】:

我检查了标准 AccountController.cs 文件的源代码,发现了两种方法

public ActionResult ChangePasswordSuccess()

    return View("ChangePasswordSuccess");

public ActionResult RestorePasswordSuccess()

    return View("RestorePasswordSuccess");

只显示相应的视图。所以我的

public ActionResult ShowDeleteSelfMessage()

    return View("DeleteSelf");

这种方法在这样的公司中看起来不错。虽然我应该更改名称以保持一致性。

【讨论】:

【参考方案3】:

Delete 操作中,而不是return View("DeleteSelf"),试试这个return Redirect("DeleteSelf")

【讨论】:

我尝试并了解到不幸的是这相当于 RedirectToAction("DeleteSelf") 那和你的OP是不是有区别,就是return View("DeleteSelf")? 不幸的是一样。但我认为现在添加单独的动作来显示视图是常见的模式。

以上是关于在没有 RedirectToAction() 的 SignOut() 之后清除 Request.IsAuthenticated 值的主要内容,如果未能解决你的问题,请参考以下文章

.NET MVC 是不是具有强类型的 RedirectToAction?

区域之间的 RedirectToAction?

RedirectToAction在控制器中工作,但不更新视图和URL

使用 RedirectToAction 传递 TempData

关于ajax载入窗口使用RedirectToAction在窗口显示的问题

ASP.NET MVC RedirectToAction 在从视图中发布 AJAX 后不起作用