【问题标题】:Handling session time out when ajax call to C# mvc controller not working当对 C# mvc 控制器的 ajax 调用不起作用时处理会话超时
【发布时间】:2012-10-03 07:38:49
【问题描述】:

从 ajax 调用函数时。程序流程无法识别过期会话,即不会重定向到登录页面。取而代之的是,它保存了记录。我在 c# .net mvc 中工作。那么我如何在ajax调用时处理会话。这里我给出了我的代码。

 $.ajax({ 
            type: "POST",
            url:'/Employee/SaveEmployee',
            data:
            {
                Location:$("#txtLocation").val(), 
                dateApplied:$("#txtDateApplied").val(), 
                Status:$("#ddStatus").val(), 
                mailCheck:$("#ddMailCheck").val(),
                ...
                ...
                ... 
            },
            success: function (result) 
            {

            },
            error: function (msg) 
            {
            }
      });

这里是控制器

[Authorize]
public string SaveEmployee(string Location, string dateApplied, string Status, string mailCheck, ...)
{
      objEmpMain.FirstName = firstName;
      objEmpMain.LastName = lastName;
      objEmpMain.Initial = Initial;
      objEmpMain.Address1 = Address;
      ...
      ... 
      ...
} 

【问题讨论】:

    标签: c# asp.net-mvc session-timeout


    【解决方案1】:

    您的 AJAX 调用的结果仍然可能最终显示为成功(尽管,请放心,它实际上不会执行您的操作方法),并调用您的 success 处理程序。这是因为您期待 HTML,这就是您收到的内容(尽管生成的 HTML 可能是您的登录页面,而不是您想要的 HTML)。顺便说一句,如果您希望使用 JSON(使用 dataType:'JSON'),则会触发错误,因为它将 HTML 解析为 JSON。

    您需要做的是阻止 FormsAuth 为 AJAX 请求重定向登录页面。现在,AuthorizeAttribute 忠实地返回了一个NotAuthorizedResult,它向客户端发送了一个 HTTP 401 Not Authorized 响应,这对于您的 AJAX 客户端来说是理想的。

    问题在于 FormsAuth 模块会检查 StatusCode,如果它是 401,它会执行重定向。我以这种方式解决了这个问题:

    1) 创建我自己的派生类型AuthorizeAttribute,在HttpContext.Items 中放置一个标志,让我知道授权失败,我应该强制执行 401 而不是重定向:

    public class AjaxAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// Processes HTTP requests that fail authorization.
        /// </summary>
        /// <param name="filterContext">Encapsulates the information for using <see cref="T:System.Web.Mvc.AuthorizeAttribute"/>. The <paramref name="filterContext"/> object contains the controller, HTTP context, request context, action result, and route data.</param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest()) filterContext.HttpContext.Items["AjaxPermissionDenied"] = true;
    
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
    

    2) 添加到您的 Global.asax.cs:

        protected void Application_EndRequest(Object sender, EventArgs e)
        {
            if (Context.Items["AjaxPermissionDenied"] is bool)
            {
                Context.Response.StatusCode = 401;
                Context.Response.End();
            }
         }
    

    3) 将 statusCode 处理程序添加到您的 jQuery AJAX 设置中:

    $.ajaxSetup({
        statusCode: {
            401: function() {
                window.location.href = "path/to/login";
            }
        }
    });
    

    4) 将您希望此行为的控制器或操作从使用 AuthorizeAttribute 更改为 AjaxAuthorizeAttribute

    [AjaxAuthorize]
    public string SaveEmployee(string Location, string dateApplied, string Status, string mailCheck, ...)
    {
          objEmpMain.FirstName = firstName;
          objEmpMain.LastName = lastName;
          objEmpMain.Initial = Initial;
          objEmpMain.Address1 = Address;
          ...
          ... 
          ...
    } 
    

    【讨论】:

    • 实际上我现在的班级看起来像下面的“公共班级EmployeeController:Controller”。您是否指示我更改如下“public class AjaxAuthorizeAttribute : AuthorizeAttribute”????
    • 只需将AuthorizeAttribute 替换为您在控制器或控制器操作上装饰的AjaxAuthorizeAttribute。请参阅我刚刚添加的#4。
    • 对不起,你能解释一下我需要在哪里创建“公共类 AjaxAuthorizeAttribute : AuthorizeAttribute”类吗???
    • 为了您的信息,我已经处理了会话超时。但它适用于视图中的函数调用。但只有 ajax 调用才是主要问题。
    • @HackedByChinese - 你的解决方案效果很好。只是一个后续问题 - 为什么在 Application_EndRequest 中调用 Context.Response.End()?
    【解决方案2】:

    我建议您使用 StatusCode = 306。 我在使用 401 时遇到了一些问题。IIS 对待 401 的方式与我理解的不同。 306 对我来说很好用。

    问候。

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 2012-05-22
      • 2017-12-30
      • 2014-12-13
      • 2013-01-20
      • 2014-09-04
      • 1970-01-01
      • 2019-08-16
      相关资源
      最近更新 更多