0

我有一个 ASP.NET MVC 4 应用程序,其中我在会话超时过滤器处理程序中捕获会话超时以处理会话超时。我还想处理 ajax 请求的会话超时。我最初在这里实现了我在这个问题中找到的代码。

这最初对自动完成和其他 ajax 调用很有用,但唯一的问题是对模态弹出窗口的 ajax 调用!

所以现在我将会话超时处理程序更改为如下所示:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (filterContext.HttpContext.Session != null)
    {
        if (filterContext.HttpContext.Session.IsNewSession)
        {
            var sessionStateDetails =(SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");
            var sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"];

            if ((sessionCookie != null) && (sessionCookie.IndexOf(sessionStateDetails.CookieName) >= 0))
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.HttpContext.Response.Clear();
                    filterContext.HttpContext.Response.StatusCode = 500;

即将状态码设置为 500(401 对我不起作用,因为我使用的是 Windows 身份验证和模拟,所以如果我将状态更改为 401,我会收到密码和用户名的安全弹出窗口)。

然后我将其捕获在 .ajaxSetup 或 .ajaxError 中,我都尝试过...并重定向到我的会话超时操作(根据需要)以显示会话超时的视图。

$(document).ajaxError(function (xhr, props) {
    if (props.status === 500) {
        ////session redirect goes here 
        var pathArray = window.location.pathname.split('/');
        var segment_1 = pathArray[1];
        var newURL = window.location.protocol + "//" + window.location.host + "/" + segment_1 + "/Home/SessionTimeout";
        window.location = newURL;
    }
});

问题是在 re-direct 之前,ajax 弹出窗口仍然短暂打开。所以看起来不太好。知道如何防止它完全打开并顺利重新定向吗?

这是我的 jQuery 对话框代码:

$(document).ready(function () {
    $(".openDialog").live("click", function (e) {
        e.preventDefault();
        $("<div></div>")
            .addClass("dialog")
            .attr("id", $(this)
            .attr("data-dialog-id"))
            .appendTo("body")
            .dialog({
                title: $(this).attr("data-dialog-title"),
                close: function () { $(this).remove() },
                width: 600,
                modal: true,
                height: 'auto',
                show: 'fade',
                hide: 'fade',
                resizable: 'false'
            })
        .load(this.href);

    });

    $(".close").live("click", function (e) {
        e.preventDefault();
        $(this).closest(".dialog").dialog("close");
    });
});

任何帮助将不胜感激,我想我几乎就在那里。

4

2 回答 2

2

我最终设法让这个工作,如果其他人有同样的问题,这就是我所做的......我一直使用会话处理程序,但我现在提出了 403 而不是 500 ,因为提出了 500 是显然是错误的,并且有一些不良副作用:

代码来自

                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.HttpContext.Response.Clear();
                    filterContext.HttpContext.Response.StatusCode = 403;

                }
                else ...usual code goes here ....

然后我捕获ajax错误如下:

$(document).ajaxError(function (xhr, props) {
    if (props.status == 403 ) {
        ////session redirect goes here 
        var pathArray = window.location.pathname.split('/');
        var segment_1 = pathArray[1];
        var newURL = window.location.protocol + "//" + window.location.host + "/" + segment_1 + "/Home/SessionTimeout";
        window.location = newURL;
    }
});

当然,我的弹出窗口仍然会在重定向之前尝试加载最短的时间,但我的用户似乎并不介意。

于 2013-08-22T15:22:39.713 回答
0

删除您的覆盖public override void OnActionExecuting(ActionExecutingContext filterContext)并使用(在 global.asax 中):

    protected void Application_EndRequest(object sender, EventArgs args)
    {

        HttpContextWrapper context = new HttpContextWrapper(Context);
        if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
            context.Response.RedirectLocation = string.Empty;
        //MiniProfiler.Stop();
    }

在你的 JavaScript 中:

$.ajaxSetup({ //jQuery.ajaxSetup({
    statusCode: {
        302: function () {
            __userLoginEvent = true;
        }
    }
});

$(document).ajaxStop(function () {
    if (__userLoginEvent) {
        //your redirection here

        __userLoginEvent = false;
    }
})

我使用ajaxStop是因为如果你是多个 ajax 调用,你想要一个重定向。这对我来说非常有用。

于 2013-08-16T12:58:54.640 回答