Friday 3 June 2016

ASP.NET MVC - How To Show A Popup Warning Before Session Timeout - ASP.NET MVC

This article is basically for how to add a friendly 'Session Timeout' warning alert message to your ASP.NET MVC website using simple jquery code. This helps you to:

    Display a warning message before a user's session times out and
    Allow the end-user to continue the session or log them our automatically



Session Timeout

1) Session Timeout is a property that you can set in your web.config file to control when a user session should expire.

2) Unfortunately, your end-users don't know when their session will expire unless you notify them somehow.

Popup Warning

One of the best way to notify your end-users is using a popup warning dialog. You may have seen these types of popups on your bank's website.

Web.Config Form Authentication code:-



<system.web>
    <httpRuntime maxRequestLength="1048576" executionTimeout="36000" targetFramework="4.5" requestValidationMode="2.0" />
    <compilation debug="true" targetFramework="4.5" />
    <authentication mode="Forms">
      <forms loginUrl="~/Login/Login" timeout="3" slidingExpiration="true" />
    </authentication>
</system.web>


Layout Page:-

Alert message html added in layout page.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    <li>@Html.ActionLink("Crop Images", "CropImage", "Home")</li>
                    <li>@Html.ActionLink("Fb Like Crop Images", "CropImageLikeFb", "Home")</li>
                    <li>@Html.ActionLink("Croper Image", "CroperImage", "Home")</li>
                    <li>@Html.ActionLink("Demo Croper Image", "DemoCropper", "Home")</li>
                </ul>
                @Html.Partial("_LoginPartial")
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

 

<div id="divPopupTimeOut" style="display:none; text-align: left; margin-top:15px; width:280px !important; position:fixed; top:40px; right:0px; z-index:9999; height:165px;" class="alert alert-warning">
    <div class="row" style="margin-top:10px; margin-left:10px;">
        Your session is about to expire! 
        <br />
        <span id="CountDownHolder"></span>
        <br />
        Click OK to continue your session.
    </div>
    <div class="row">
        <div class="text-center button-block" style="text-align:center; margin-top:22px;">
            <button type="button" class="btn btn-default btn-sm" onclick="SessionTimeout.sendKeepAlive();">@ResourcesLang.OK</button>
            <button type="button" class="btn btn-default btn-sm" onclick="SessionTimeout.hidePopup();">@ResourcesLang.Cancel</button>
        </div>
    </div>
</div> 
 
@functions {
    public int PopupShowDelay
    {
        get
        {
            return 1000 * (Convert.ToInt32(FormsAuthentication.Timeout.TotalSeconds) - 130);
        }
    }
 } 
 


Jquery Code:-


<script type="text/javascript">
    var loginUrl='@Url.Action("Login", "Login")';
    var extendMethodUrl='@Url.Action("ExtendSession","Dashboard")';
    $(document).ready(function(){
            SessionTimeout.schedulePopup();
        });

    window.SessionTimeout = (function() {
            var _timeLeft, _popupTimer, _countDownTimer;
            var stopTimers = function() {
                window.clearTimeout(_popupTimer);
                window.clearTimeout(_countDownTimer);
            };
            var updateCountDown = function() {
                var min = Math.floor(_timeLeft / 60);
                var sec = _timeLeft % 60;
                if(sec < 10)
                    sec = "0" + sec;

                document.getElementById("CountDownHolder").innerHTML = min + ":" + sec;

                if(_timeLeft > 0) {
                    _timeLeft--;
                    _countDownTimer = window.setTimeout(updateCountDown, 1000);
                } else  {
                    document.location = loginUrl;
                }
            };
            var showPopup = function() {
            $("#divPopupTimeOut").show();
                _timeLeft = 120;
                updateCountDown();
            };
            var schedulePopup = function() {
            $("#divPopupTimeOut").hide();
                stopTimers();
                _popupTimer = window.setTimeout(showPopup, @PopupShowDelay);
            };
            var hidePopup=function(){
            $("#divPopupTimeOut").hide();
            };
            var sendKeepAlive = function() {
                stopTimers();
                $("#divPopupTimeOut").hide();
                $.ajax({
                    type: "GET",
                    url: extendMethodUrl,
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function successFunc(response) {
                        SessionTimeout.schedulePopup();
                    },
                    error:function(){
                    }
                });
            };
            return {
                schedulePopup: schedulePopup,
                sendKeepAlive: sendKeepAlive,
                hidePopup:hidePopup,
                stopTimers:stopTimers,
            };

        })();

</script>


Controller Action method code:-

When you click on ok button in session warning message then below mentioned
method is called and it will extend the form authentication timeout time or session
time in your website.


[HttpGet]
 public ActionResult ExtendSession()
 {
    System.Web.Security.FormsAuthentication.SetAuthCookie(User.Identity.Name, false);
    var data = new { IsSuccess = true };
    return Json(data, JsonRequestBehavior.AllowGet);
 }

9 comments:

  1. Thank you for your great efforts!

    I have a modification; Check at first if user is authenticated or not:

    $(document).ready(function(){
    if('@User.Identity.IsAuthenticated' == 'True'){
    SessionTimeout.schedulePopup();
    }
    });

    Thanks,

    ReplyDelete
  2. best article ever.

    ReplyDelete
  3. nice and very useful.
    Thanks.

    ReplyDelete
  4. SIR,PLEASE GIVE ME SOURCE BECAUSE I AM FRESHER SO ERROR SHOWING

    ReplyDelete
  5. hello sir, i copy your code in my project but show me error in "@ResourcesLang"... this is for what purpose use..? and what i have to use in place of that... can you please suggest me.?

    ReplyDelete
  6. Can anyone please explain what does last piece of code (pasted below) means?

    return {
    schedulePopup: schedulePopup,
    sendKeepAlive: sendKeepAlive,
    hidePopup:hidePopup,
    stopTimers:stopTimers,
    };

    ReplyDelete
  7. Great article. It helped me a lot. Thank you.

    ReplyDelete