0

I am calling a void function using jquery ajax in mvc3. In that function when the Session is out then also it will come to success function of ajax. I need to know whether the Session is available or not before sending the request or inside the success function of ajax.

controller Action:

 protected override void Save(Query query, string queryTitle)
 {
 }
ssilas777
  • 9,672
  • 4
  • 45
  • 68
Saritha.S.R
  • 800
  • 1
  • 6
  • 19
  • I am not sure what you are trying to do here. Do you wanted to query if the session was expired or do you want to perform an action only if the user's session was not just created ? – gretro Feb 17 '14 at 05:10
  • I need to know whether session available on this Save function and I need to show an alert – Saritha.S.R Feb 17 '14 at 05:12
  • See this page it will helpfull for your problem [Handling session time out when ajax call to C# mvc controller not working][1] [1]: http://stackoverflow.com/questions/12703942/handling-session-time-out-when-ajax-call-to-c-sharp-mvc-controller-not-working – Raja Rajendraprasath Feb 17 '14 at 05:28
  • Ref this link this will helpfull for you [Handling session time out when ajax call to C# mvc controller not working][1] [1]: http://stackoverflow.com/questions/12703942/handling-session-time-out-when-ajax-call-to-c-sharp-mvc-controller-not-working. – Raja Rajendraprasath Feb 17 '14 at 05:30

4 Answers4

2

Why not catch the expiry of the session on the server, return an HTTP 401 Unauthorized, then check for this response in jquery and pop up a "Your session has expired, please log in again" page?

The code you need on the initial server call is:

protected void Save(Query query, string queryTitle)
{
    // would probably be better to refactor this bit out into its own method
    string sCookieHeader = Request.Headers["Cookie"];
    if (Context.Session != null 
        && Context.Session.IsNewSession
        && sCookieHeader != null
        && sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0)
    {
        // session has expired
        if (Request.IsAuthenticated)
        {
            FormsAuthentication.SignOut();
        }
        Response.StatusCode = 401
    }
    else
    {
        // we're authenticated, so do the save
    }
}

and on the client:

$.ajax(serverUrl, {
   data: dataToSave,
   statusCode: {
      200: function(response) {
        // all good, continue
      401: function (response) {
         // session expired!
         // show login box
         // make ajax call to reauthenticate
         // call save method again
      },
});

Your reauthentication call would look something like this:

public ActionResult Reauthenticate(username, password) 
{
    if (IsValidUser(username, password))
    {  
      // sometimes used to persist user roles
      string userData = string.Join("|",GetCustomUserRoles());

      FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
        1,                                     // ticket version
        username,                              // authenticated username
        DateTime.Now,                          // issueDate
        DateTime.Now.AddMinutes(30),           // expiryDate
        isPersistent,                          // true to persist across browser sessions
        userData,                              // can be used to store additional user data
        FormsAuthentication.FormsCookiePath);  // the path for the cookie

      // Encrypt the ticket using the machine key
      string encryptedTicket = FormsAuthentication.Encrypt(ticket);

      // Add the cookie to the request to save it
      HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
      cookie.HttpOnly = true; 
      Response.Cookies.Add(cookie);
    }
}

(Adapted from How to set HTTP status code from ASP.NET MVC 3?)

Community
  • 1
  • 1
Mike Chamberlain
  • 39,692
  • 27
  • 110
  • 158
  • It wont show any error and it will take the value as 0. I am doing like if(session available){ save to DB with value as 0} other wise I need to show an alert. – Saritha.S.R Feb 17 '14 at 05:19
  • its not possible to return anything from the function "Save", its a void function – Saritha.S.R Feb 17 '14 at 05:29
  • I don't think you read the second and third links then. You can return an HTTP status code in the HTTP headers and read this in jQuery. This is exactly what the 401 code was designed for. – Mike Chamberlain Feb 17 '14 at 05:32
  • Also take a look at this: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields – Mike Chamberlain Feb 17 '14 at 05:38
0

Why not try this ?

public void Save()
{
    if (Session.IsNewSession)
    {
        throw new Exception("This session was just created.");
    }

    //Go on with save matter...
}

This should return a status 500 on your AJAX function and should cause the response to fall in the fail method you defined.

gretro
  • 1,934
  • 15
  • 25
0

Another way is to setInterval() on the client that continually sends a dummy request to the server to keep the session alive, at least when the user is editing. This might be the best way to prevent them user from losing work. You could also use this to detect loss connectivity.

Mike Chamberlain
  • 39,692
  • 27
  • 110
  • 158
0

When the page is loaded first time , pass the current SessionId to the client side and assign to the local javascript variable.Next have a method which will return the current SessionId before making the Save method call from the AJAX , compare the local variable against the Session Id you have received.

       public string GetCurrentSessionId(){
            return HttpContext.Current.Session.SessionId;
         }

Javascript function

      $.ajax({
          Url : 'GetCurrentSessionId',
          success : function(result){
               if(result === "LOCALSESSIONID")
                      CALL THE SAVE METHOD
               else
                  alert('Session is expired');
           }

      });
Devesh
  • 4,500
  • 1
  • 17
  • 28
  • This is not robust because the session could expire between the two calls, and the user will end up losing their work without forcing them to log in again. – Mike Chamberlain Feb 17 '14 at 05:28