Ajax call when session time out

2019-04-27 10:34发布

问题:

All, I am trying to redirect to login page if making a ajax call when session timeout. Here is what I had done so far.

Define a action filter for all the action.

public class AuthenticateFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            var routeDataSet = filterContext.RouteData;
            if (LoginUser.LoginAdministrator == null)
            {
                //if the useinfo stored in session is timeout. 
                if (routeDataSet != null
                    && routeDataSet.Values["controller"] != null
                    && routeDataSet.Values["controller"].ToString().ToLower().Equals("login")
                    && routeDataSet.Values["action"] != null
                    && routeDataSet.Values["action"].ToString().ToLower().Equals("login"))
                {
                    //if it is login action itself.let it be. don't do anything.


                }
                else
                {
                    //redirect to login page.
                    filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary { { "controller", "Login" }, { "action", "Login" } });
                }
            }
        }
    }

This works for non ajax action call when session time out. But for the ajax call. It can't not redirect to login page but only return a html page string(seems it is the source html code for login page), not the really result. Say we have code like this.

function ajaxGetLogDetail(logId) {
        var sUrl = "/LogDetail/index?logId=" + logId;
        $.ajax({
            cache: false,
            type: "GET",
            async: false,
            url: sUrl,
            success: function (result) {
                //please note result is html string. not the really result.
            },
            error: function (xhr) {
                alert(xhr.responseText);
            }
        });
    }

Could anyone help to give me some clue for solving this issue? thanks.

Updated

Based on the Mohsin and Dave's answer(thanks you two), Here is the finally solution. Please review it. thanks.

public class AuthenticateFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            var routeDataSet = filterContext.RouteData;
            if (LoginUser.LoginAdministrator == null)
            {

                //&& routeDataSet != null && routeDataSet.Values["controller"] != null
                //&& !routeDataSet.Values["controller"].ToString().ToLower().Equals("login") && routeDataSet.Values["action"] != null
                //&& !routeDataSet.Values["action"].ToString().ToLower().Equals("login") && !filterContext.HttpContext.Request.HttpMethod.ToLower().Equals("get"))
                if (routeDataSet != null
                    && routeDataSet.Values["controller"] != null
                    && routeDataSet.Values["controller"].ToString().ToLower().Equals("login")
                    && routeDataSet.Values["action"] != null
                    && routeDataSet.Values["action"].ToString().ToLower().Equals("login"))
                {



                }
                else
                {
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        filterContext.Result = new JsonResult
                        {
                            Data = new
                            {
                                ErrorMessage = "SystemSessionTimeOut"
                            },
                            JsonRequestBehavior = JsonRequestBehavior.AllowGet
                        };
                    }
                    else
                    {
                        filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary { { "controller", "Login" }, { "action", "Login" } });
                    }
                }
            }
        }
    }

On the client side :

function ajaxGetLogDetail(logId) {
        var sUrl = "/LogDetail/index?logId=" + logId;
        $.ajax({
            cache: false,
            type: "GET",
            async: false,
            url: sUrl,
            success: function (result) {
                if (result.ErrorMessage=="SystemSessionTimeOut")
                {
                   windows.location="/Login/Login";
                } 
                else
                {
                   //...  
                }
            },
            error: function (xhr) {
                alert(xhr.responseText);
            }
        });
    }

回答1:

Ajax calls CANNOT return a redirect of any kind. At core an AJAX call only returns a string. There is no Engine of the kind that will perform a redirect.

You CAN perform a client side redirect though. If the Session has timed out and on client side have your Controller Method return false:

     if !(routeDataSet != null
         && routeDataSet.Values["controller"] != null
         && routeDataSet.Values["controller"].ToString().ToLower().Equals("login")
         && routeDataSet.Values["action"] != null
         && routeDataSet.Values["action"].ToString().ToLower().Equals("login"))
      {
        return Json(new { success = false, message = errorMessage });
      }

In your AJAX error function:

        error: function (xhr) {
            alert(xhr.responseText);
            window.location='/Login/Login';
        }

Side note: was your destination meant to be '/Login/Login' or '/Account/Login'