【问题标题】:MVC4 Partial View Ajax Load with AuthorizationMVC4 部分视图 Ajax 加载授权
【发布时间】:2014-04-17 20:11:55
【问题描述】:

我将尝试尽可能地解释这一点。所以,这是我的问题。

我有一个控制器,它有两个动作(我们将使用 Index 动作调用这个 Controller1)一个使用 HttpGet 属性,另一个使用 HttpPost 属性,并且都使用 Authorize 属性来确保某人通过了身份验证。

Controller1.Index 视图使用一个局部视图,它调用一个名为 _Commands 的视图(也在 Controller1 控制器上)。这个局部视图在控制器中也有与之关联的 Authorize 属性。

如果用户未获得授权,他们将被强制使用登录控制器 (LoginController),该控制器具有与之关联的 Get 和 Post 属性(索引操作)。

Controller1.Index 通过名为 GetRecord 的操作调用局部视图。如果记录存在,它会呈现 Partial(返回 PartialView),如果不存在,它几乎只会呈现一个空白 DIV。这一切都是通过使用 POST ajax 调用的 Jquery .ajax 调用完成的。

但是,问题是当用户长时间坐在页面上并且他们的会话过期时,他执行了一个 jquery 事件(比如更改触发 ajax 调用以更新部分的下拉菜单), partial 使用 Login.Index 视图呈现(并调用 LoginController.Index GET 操作),_Command partial 应该在哪里。

现在我的问题是,如何强制登录屏幕“退出”任何部分调用,然后重新加载为首页?

我尝试了一些不起作用的方法。例如,我在登录 GET 中尝试了 Request.IsAjaxRequest,但没有任何效果。我也试过 IsChildAction,没有效果。两者都返回 FALSE。

还有其他人知道我可以如何解决这个问题吗?

【问题讨论】:

  • 数十个 SO 问题的可能重复项,可在 Google 上搜索为“asp.net 捕获未经授权的 ajax 请求”。

标签: c# asp.net-mvc asp.net-mvc-4 partial-views


【解决方案1】:

以下是最近项目中对我有用的方法。

首先,在一个全局 js 文件中,我设置了以下内容:

$.ajaxSetup({
        error: function (xhr, textStatus, errorThrown) {
            //make sure this isn't caused by navigating away from the page by checking the xhr readyState
            if (xhr.readyState == 4) {

                switch (xhr.status) {
                    case 401:
                    case 403:
                        // take them to the login but hang on to their current url
                            //calling reload does this by leveraging the rest of our framework automagically!
                        window.location.reload(true);
                        break;
                    default:
                        bootbox.alert('<div class="text-center"><h2>An error was encountered</h2><h3>Sorry, an error has occurred.  The system administrators have been notified.</h3></div>');
                        break;
                }
            }
        }
    });

显然,整个页面重新加载已经处理引导用户重新登录,所以我只检测到 403 并强制页面重新加载。那里还有一些其他的 ajax 错误处理,这对于您的请求不是必需的。

现在,403 不是默认的 unauth 状态,所以为了实现这一点,我有一个自定义的 auth 属性:

public class AuthorizationRequiredAttribute : AuthorizeAttribute
{
    #region Overrides of AuthorizeAttribute

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var skipAuthorization =
            filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) ||
            filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);

        if (skipAuthorization) return;

        base.OnAuthorization(filterContext);

        //now look to see if this is an ajax request, and if so, we'll return a custom status code
        if (filterContext.Result == null) return;

        if (filterContext.Result.GetType() == typeof (HttpUnauthorizedResult) &&
            filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new ContentResult();
            filterContext.HttpContext.Response.StatusCode = 403;
        }
    }
    #endregion
}

有一些原因(我现在不记得了,但我很确定我从 SO 上的其他地方得到了信息)你不能依赖标准的 unauth 状态代码,因此必须用 403 覆盖它。希望这有帮助!

【讨论】:

    猜你喜欢
    • 2012-12-09
    • 2013-01-09
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 2016-03-12
    相关资源
    最近更新 更多