2020年11月23日 星期一

[研究] HTML, CSS, JavaScript, jQuery, jQuery UI, Bootstrap 彈出對話盒視窗

[研究] HTML, CSS, JavaScript,  jQuery, jQuery UI, Bootstrap 警告(Alert)、對話盒 (Dialog)、彈出視窗(Popup Window)、彈出對話盒(Popup Dialog)、彈出對話盒視窗(Popup Dialog Window)

2020-11-23

HTML 對話盒視窗因為是平面式而非彈出式,少人用。

CSS 對話盒視窗感覺是平面式的,只是Modal會以區塊覆蓋顯示於其他內容上。

JavaScript 彈出對話盒視窗是比較多人用的。但以 alert()、confirm()、prompt()、windows.open() 較常用,其他較少用,且非每種瀏覽器或版本都支援,有些雖支援,但預設沒有啟用。

jQuery 是用 JavaScript 開發的,沒有特別提供的對話盒。

jQuery UI 需要 jQuery,主要強化 UI ( User Interface,使用者介面) 部分。

BootStrap 3.x 和 4.x 需要 jQuery,但未來推出的 5.x 不需要 jQeury。BootStrapAlert對話盒是平面式而非彈出式,少人用。Bootstrap Modal Plugin 是彈出式的。

比較進階強化的對話盒,混用的 HTML, CSS, JavaScript,  jQuery, jQuery UI, Bootstrap 等標準和技術。網路上某些程式範例,可能已經淘汰,或不支援新版的套件,無法正常運作。

********************************************************************************

HTML

HTML <dialog> Tag

https://www.w3schools.com/tags/tag_dialog.asp

HTML 範例:<dialog open>This is an open dialog window</dialog>

(下圖) 直接顯示在網頁上的對話盒視窗,而非彈出式的。

可用下面 JavaScript 操作 (但也可操作非 HTML <dialog> Tag )

HTML DOM Dialog Object,包含 document.getElementById(), document.createElement(), open, close(), show(), showModal() 等。 

https://www.w3schools.com/jsref/dom_obj_dialog.asp

********************************************************************************

CSS

W3.CSS Alerts,平面式警告對話盒,其實是使用 w3-panel

https://www.w3schools.com/w3css/w3css_alerts.asp

W3.CSS Modal

https://www.w3schools.com/w3css/w3css_modal.asp



<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>

<div class="w3-container">
  <h2>W3.CSS Modal</h2>
  <button onclick="document.getElementById('id01').style.display='block'" class="w3-button w3-black">Open Modal</button>
test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test 
  <div id="id01" class="w3-modal">
    <div class="w3-modal-content">
      <div class="w3-container">
        <span onclick="document.getElementById('id01').style.display='none'" class="w3-button w3-display-topright">&times;</span>
        <p>Some text. Some text. Some text.</p>
        <p>Some text. Some text. Some text.</p>
      </div>
    </div>
  </div>
</div>
            
</body>
</html>

(下圖)看起來像是平面式的對話盒,只是會覆蓋顯示於其他網頁內容上。

********************************************************************************

JavaScript

alert()、confirm()、prompt()

https://www.w3schools.com/js/js_popup.asp

alert()

https://www.w3schools.com/jsref/met_win_alert.asp

****************************************

confirm()

https://www.w3schools.com/jsref/met_win_confirm.asp

****************************************

prompt()

https://www.w3schools.com/jsref/met_win_prompt.asp


****************************************

windows.open() 

https://www.w3schools.com/jsref/met_win_open.asp

另外開啟新瀏覽器視窗,載入某址的網頁

****************************************

HTML DOM Dialog Object,包含 document.getElementById(), document.createElement(), open, close(), show(), showModal() 等。 

https://www.w3schools.com/jsref/dom_obj_dialog.asp

JavaScript 建立:var x = document.createElement("DIALOG");

JavaScript 存取:var x = document.getElementById("myDialog");

JavaScript,判斷是否開啟(不會實際去開啟):var x = document.getElementById("myDialog").open;

https://www.w3schools.com/jsref/prop_dialog_open.asp

Dialog close() Method

https://www.w3schools.com/jsref/met_dialog_close.asp

showModal()

https://www.w3schools.com/jsref/met_dialog_showmodal.asp



<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>Click the button to show the dialog.</p>
    <button onclick="myFunction()">Show dialog</button>
    <p><b>Note:</b> Use the "Esc" button to close the modal.</p>
    <p><b>Note:</b> The dialog element is only supported in Chrome 37+, Safari 6+ and Opera 24+.</p>
    <dialog id="myDialog">This is a dialog window</dialog>
    <script>
        function myFunction() {
            document.getElementById("myDialog").showModal();
        }
    </script>
</body>
</html>

(下圖)Google Chrome 版本 87.0.4280.66 (正式版本) (64 位元)、Miccrosoft Edge 86



(下圖) IE11


FireFox 83 按下「Show Dialog」按鈕沒有反應。

****************************************

showModalDialog() 和 showModalessDialog() 不是標準,僅某些瀏覽器和版本支援。

********************************************************************************

jQuery UI

jQuery UI 需要 jQuery,主要強化 UI ( User Interface,使用者介面) 部分。

Dialog

https://jqueryui.com/dialog/

官方範例使用的路徑稍作修正如下

Test.htm


<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Dialog - Default functionality</title>
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <link rel="stylesheet" href="https://jqueryui.com/resources/demos/style.css">
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
  $( function() {
    $( "#dialog" ).dialog();
  } );
  </script>
</head>
<body>
 
<div id="dialog" title="Basic dialog">
  <p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the &apos;x&apos; icon.</p>
</div>
 
 
</body>
</html>

(下圖) 執行結果

********************************************************************************

Bootstrap

Bootstrap Alert ( Bootstrap 3 和 4 需要 jQuery, 未來Bootstrap 5 不需要 jQuery)

https://www.w3schools.com/bootstrap/bootstrap_alerts.asp


<div class="alert alert-success">
  <strong>Success!</strong> Indicates a successful or positive action.
</div>

<div class="alert alert-info">
  <strong>Info!</strong> Indicates a neutral informative change or action.
</div>

<div class="alert alert-warning">
  <strong>Warning!</strong> Indicates a warning that might need attention.
</div>

<div class="alert alert-danger">
  <strong>Danger!</strong> Indicates a dangerous or potentially negative action.
</div>

Bootstrap Alert 比較不像 JavaScript 傳統 alert(),它不會彈出對話盒或彈出視窗,而是平面文字框,比較像是用 CSS 去達成的。

****************************************

Bootstrap Modal Plugin

https://www.w3schools.com/bootstrap/bootstrap_modal.asp

only supported in Chrome 37+, Safari 6+ and Opera 24+.


<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
  <h2>Modal Example</h2>
  <!-- Trigger the modal with a button -->
  <button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>

  <!-- Modal -->
  <div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">
    
      <!-- Modal content-->
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Modal Header</h4>
        </div>
        <div class="modal-body">
          <p>Some text in the modal.</p>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>
      
    </div>
  </div>
  
</div>

</body>
</html>

(下圖) 對話盒是彈出式的

********************************************************************************


(完)

相關

谷歌,火狐瀏覽器不支援showModalDialog的解決方法

其他 · 發表 2019-02-13

https://www.itread01.com/content/1549994237.html


2020年11月18日 星期三

[研究]]JavaScript] 用 orangehill / bootstrap-session-timeout 做 Session Time Out 前 N 秒自動彈出對話盒視窗

[研究]]JavaScript] 用 orangehill / bootstrap-session-timeout 做 Session Time Out 前 N 秒自動彈出對話盒視窗

2020-11-18

orangehill / bootstrap-session-timeout

最後版本1.0.3,於 2015-07-17釋出

https://github.com/orangehill/bootstrap-session-timeout



<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" 
Inherits="WebApplication11.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <%--bootstrap 和 jQuery 用 NuGet 安裝--%>
    <link href="Content/bootstrap.css" rel="stylesheet" />
    <script src="Scripts/jquery-3.5.1.js"></script>
    <script src="Scripts/bootstrap.js"></script>

    <%--bootstrap-session-timeout.js 去官方網站手動下載,放到 Scripts 目錄
    https://github.com/orangehill/bootstrap-session-timeout
        --%>
    <script src="Scripts/bootstrap-session-timeout.js"></script>
</head>
<body>
    <%--參考
    https://github.com/orangehill/bootstrap-session-timeout/blob/master/examples/basic.html
        --%>
    <form id="form1" runat="server">
        <div>
           <p>Shows the warning dialog after 3 seconds. <br />
               If user takes no action (interacts with the page in any way), 
browser is redirected to redirUrl. 
On any user action (mouse, keyboard or touch) the timeout timer is reset. </p>
        </div>
    </form>
     
    <script>
    $.sessionTimeout({
        keepAliveUrl: 'keep-alive.html',
        logoutUrl: 'login.html',
        redirUrl: 'locked.html',
        warnAfter: 3000,
        redirAfter: 10000
    });
    </script>
</body>
</html>

結果


********************************************************************************

補充:結果等了 3 秒沒反應,或者出現下面錯誤,請檢查 bootstrap-session-timeout.js 內容是否正確。




(下圖) bootstrap-session-timeout.js 正確內容



(下圖) bootstrap-session-timeout.js 錯誤內容

********************************************************************************

補充:若因某原因在 bootstrap-session-timeout.cs 之前後都載入 jquery,js


    <script src="Scripts/jquery-3.5.1.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/bootstrap-session-timeout.js"></script>
    <script src="Scripts/jquery-3.5.1.js"></script>

或 jquery.js 和 bootstrap.js 在 bootstrap-session-timeout.js.js 之後


    <link href="Content/bootstrap.css" rel="stylesheet" />
    <script src="Scripts/bootstrap-session-timeout.js.js"></script>
    <script src="Scripts/jquery-3.5.1.js"></script>
    <script src="Scripts/bootstrap.js"></script>

或  <asp:ScriptReference Name="jquery" /> 

會有下面錯誤

錯誤: 物件沒有支援這個屬性或方法 'sessionTimeout'

********************************************************************************

補充:若 jquery 在 bootstrap-session-timeout.cs 之後都載入


    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/bootstrap-session-timeout.js"></script>
    <script src="Scripts/jquery-3.5.1.js"></script>

會有下面錯誤

錯誤: Bootstrap's JavaScript requires jQuery



(完)

[研究][JavaScript] 用 session-timeout.js 做 Session Time Out 前 N 秒自動彈出對話盒視窗

[研究][JavaScript] 用 session-timeout.js 做 Session Time Out 前 N 秒自動彈出對話盒視窗

2020-11-18

travishorn / session-timeout
最後釋出 2020-04-xx
https://github.com/travishorn/session-timeout
這是 jquery-sessionTimeout 後繼版本


travishorn / jquery-sessionTimeout
最後釋出2014-xx-xx
http://travishorn.github.io/jquery-sessionTimeout/
https://github.com/travishorn/jquery-sessionTimeout


測試環境:Visual Studio 2019 v16.8.1 + C# + ASP.NET + WebForm

Default.aspx


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" 
Inherits="WebApplication10.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>

    <%--成功--%>
    <script src="https://unpkg.com/@travishorn/session-timeout"></script>
    <%--所以按鈕文字不能換成中文,只能用英文--%>

    <%--失敗,把 session-timeout.js 下載拿來用不行--%>
    <script src="Scripts/session-timeout.js"></script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <%--<%--travishorn / session-timeout--%>
            <%--https://github.com/travishorn/session-timeout --%>
           等6秒(6000毫秒)後會彈出視窗。
        </div>
    </form>
    <script>
        sessionTimeout({
            warnAfter: 6000,
            message: 'Are you still there?',
        });
    </script>
</body>
</html>


Default.aspx.cs 不用改
執行結果

沒有倒數計時、沒有轉址、沒有中文訊息。

**********

2020-11-19 發現不能用了,原因不明。

錯誤: 物件沒有支援這個屬性或方法 'assign'



(完)

[研究] AjaxControlToolkit ToolkitScriptManager 元素不是已知元素

[研究] AjaxControlToolkit ToolkitScriptManager 元素不是已知元素

2020-11-18

本想拿來做 Session Time Out 自動倒數計時、彈出對話盒視窗 使用。

開始使用 AJAX Control Toolkit (C#)

https://docs.microsoft.com/zh-tw/aspnet/web-forms/overview/ajax-control-toolkit/getting-started/get-started-with-the-ajax-control-toolkit-cs


AjaxControlToolkit 官方網站 & 下載網址

https://www.devexpress.com/Products/AJAX-Control-Toolkit/

Visual Studo 2019 v16.8.1 用 NuGet 安裝 AjaxControlToolkit 20.1.0

結果 ModalPopupExtender 正常,但 ToolkitScriptManager 異常。


ToolkitScriptManager 元素不是已知元素。

ToolkitScriptManager is not a known element


Google 查知 NuGet 安裝的 AjaxControlToolkit 不含 ToolkitScriptManager,要去官方網站下載的才包含。

考慮升級套件麻煩問題,暫時放棄了。

(完)



[研究][JavaScript]Master Page 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗

[研究][JavaScript]Master Page 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗

2020-11-18

續這篇

[研究][JavaScript] 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗

http://shaurong.blogspot.com/2020/11/javascript-idle-timerjs-session-time.html


環境 Visual Studio 2019 v16.8.1 版 + C# + ASP.NET  + WebForm + 主版頁面 Master Page

NuGet 要安裝數個套件,jQuery, BootStrap, popper, moment,不確定是否可缺。

敝人測試用 BootStrap 3.5.1 或 4.x 都可以用。

jQuery Idle Timer Plugin 要手動下載,把 idle-timer.js 拿過來用 ( 一個檔案就好)

https://github.com/thorst/jquery-idletimer


Download

Compressed ~3kb

https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js

Uncompressed ~11kb

https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.js

不要另存新檔,下載 src 目錄下的 idle-timer.js,那個不是。


正確的內容


根據下面網址,jQuery Idle Timer Plugin 目前為 v1.1.1 2020-06-25 版

https://raw.githubusercontent.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js



packages.conf

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="bootstrap" version="3.4.1" targetFramework="net472" />
  <package id="jQuery" version="3.5.1" targetFramework="net472" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net472" />
  <package id="Moment.js" version="2.29.1" targetFramework="net472" />
  <package id="popper.js" version="1.16.1" targetFramework="net472" />
</packages>

Site1.Master


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="WebApplication1.Site1" %>

<!DOCTYPE html>

<html>
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <%--相依性可能影響順序先後,但這個順序可用--%>
    <script src="Scripts/jquery-3.5.1.js"></script>
    <script src="Scripts/idle-timer.js"></script>
    <link href="Content/bootstrap.css" rel="stylesheet" />
    <script src="Scripts/popper.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/moment.js"></script>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
        <div class="container">
            <h2>Concept</h2>
            <p>
                Wait 10 seconds, you will see a expiring warning. Wait 10 more seconds and you will see that you have been logged out.
       
            </p>

        </div>
        <div class="modal fade" id="mdlExpirationWarning" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">Session Expiration Warning</h5>

                    </div>
                    <div class="modal-body">
                        <p>You've been inactive for a while. For your security, we'll log you out automatically. Click "Stay Online" to continue your session. </p>
                        <p>
                            Your session will expire in <span class="bold" id="sessionSecondsRemaining">120</span> seconds.
                   
                        </p>
                    </div>
                    <div class="modal-footer">
                        <button id="extendSession" type="button" class="btn btn-primary" data-dismiss="modal">
                            Stay
                        Online</button>
                        <button id="logoutSession" type="button" class="btn btn-secondary">Logout</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="modal fade" id="mdlLoggedOut" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">You have been logged out</h5>
                    </div>
                    <div class="modal-body">
                        <p>Your session has expired.</p>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
    </form>
    <script>
        // You could pull this out to its own file very easily
        window.app = window.app || {};

        app.session = {

            //Settings
            warningTimeout: 10000, //(ms) The time we give them to say they want to stay signed in
            inactiveTimeout: 20000, //(ms) The time until we display a warning message
            minWarning: 5000, //(ms) If they come back to page (on mobile), The minumum amount, before we just log them out
            timerSyncId: "SomethingUnique", //The key idleTimer will use to write to localStorage
            logoutUrl: "/logout", //Your url to log out, if you want you could build the url to pass a referal param
            keepAliveUrl: "api/user/KeepAlive", // The url for the keepalive api
            keepaliveInterval: 5000, //(ms) the interval to call keep alive url
            //From here down you shouldnt have to alter anything
            warningStart: null, //Date time the warning was started
            warningTimer: null, //Timer running every second to countdown to logout
            keepaliveTimer: null, //Timer for independent ping to keep session alive
            logout: function () {
                //Write to storage to tell other tab its time to sign out
                if (typeof (localStorage) !== "undefined") {
                    localStorage.setItem(app.session.timerSyncId, 0);
                }

                //Send this page to the logout url, that will destroy session and forward to login
                //window.location = app.session.logoutUrl;

                //To simulate logout we are just showing the logout dialog and locking the screen
                $("#mdlExpirationWarning").modal("hide");
                $("#mdlLoggedOut").modal("show");
            },
            keepAlive: function () {
                //Hide logout modal
                $("#mdlExpirationWarning").modal("hide");

                //Clear the timer
                clearTimeout(app.session.warningTimer);
                app.session.warningTimer = null;

                //Restart the idleTimer
                $(document).idleTimer("reset");
            },
            startKeepAliveTimer: function () {
                // Basically I just poll the server half way through the session life
                // to make sure the servers session stays valid
                clearTimeout(app.session.keepaliveTimer);
                app.session.keepaliveTimer = setInterval(function () {
                    app.session.sendKeepAlive();
                }, (app.session.inactiveTimeout / 2));
            },
            sendKeepAlive: function () {
                // Write a new date to storage so any other tabs are informed that this tab
                //  sent the keepalive
                if (typeof (localStorage) !== "undefined") {
                    localStorage.setItem(app.session.timerSyncId + "_keepalive", +new Date());
                }

                // The actual call to the keep alive api
                //$.post(app.session.keepAliveUrl).fail(function (jqXHR) {
                //    if (jqXHR.status == 500 || jqXHR.status == 0) {
                //        app.session.logout();
                //    }
                //});
            },
            showWarning: function (obj) {
                //Get time when user was last active
                var diff = (+new Date()) - obj.lastActive - obj.timeout,
                    warning = (+new Date()) - diff;

                // Destroy idleTimer so users are forced to click the extend button
                $(document).idleTimer("pause");

                //On mobile js is paused, so see if this was triggered while we were sleeping
                if (diff >= app.session.warningTimeout || warning <= app.session.minWarning) {
                    app.session.logout();
                } else {

                    //Show dialog, and note the time
                    $('#sessionSecondsRemaining').html(Math.round((app.session.warningTimeout - diff) / 1000));
                    $("#mdlExpirationWarning").modal("show");
                    app.session.warningStart = (+new Date()) - diff;

                    //Update counter downer every second
                    app.session.warningTimer = setInterval(function () {
                        var remaining = Math.round((app.session.warningTimeout / 1000) - (((+new Date()) - app.session.warningStart) / 1000));

                        if (remaining >= 0) {
                            $('#sessionSecondsRemaining').html(remaining);
                        } else {
                            app.session.logout();
                        }
                    }, 1000)
                }
            },
            localWrite: function (e) {

                if (typeof (localStorage) !== "undefined" && e.originalEvent.key == app.session.timerSyncId && app.session.warningTimer != null) {
                    // If another tab has written to cache then
                    if (e.originalEvent.newValue == 0) {
                        // If they wrote a 0 that means they chose to logout when prompted
                        app.session.logout();
                    } else {
                        // They chose to stay online, so hide the dialog
                        app.session.keepAlive();
                    }

                } else if (typeof (localStorage) !== "undefined" && e.originalEvent.key == app.session.timerSyncId + "_keepalive") {
                    // If the other tab sent a keepAlive poll to the server, reset the time here so we dont send two updates
                    // This isnt really needed per se but it will save some server load
                    app.session.startKeepAliveTimer();
                }
            }
        };

        $(function () {
            //This will fire at X after page load, to show an inactive warning
            $(document).on("idle.idleTimer", function (event, elem, obj) {
                app.session.showWarning(obj);
            });

            //Create a timer to keep server session alive, independent of idleTimer
            app.session.startKeepAliveTimer();

            //User clicked ok to extend session
            $("#extendSession").click(function () {
                app.session.keepAlive(); //Remove the warning dialog etc
            });

            //User clicked logout
            $("#logoutSession").click(function () {
                app.session.logout();
            });

            //Set up the idleTimer, if inactive for X seconds log them out
            $(document).idleTimer({
                timeout: app.session.inactiveTimeout - app.session.warningTimeout,
                timerSyncId: app.session.timerSyncId
            });

            // Monitor writes by other tabs
            $(window).bind("storage", app.session.localWrite);
        });
    </script>
</body>
</html>

Site1.Master.cs  (不用特別去修改)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Site1 : System.Web.UI.MasterPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

Default.aspx  (不用特別去修改)


<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>

Default.aspx.cs  (不用特別去修改)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

Web.Config (預設 20 分鐘,可以不用特別去設定)

<configuration>
  <system.web>
    <sessionState timeout="20"></sessionState>
  </system.web>
</configuration>

(下圖)執行結果,等10秒就會出現




(完)

相關

[研究] AjaxControlToolkit ToolkitScriptManager 元素不是已知元素
http://shaurong.blogspot.com/2020/11/ajaxcontroltoolkit-toolkitscriptmanager.html

[研究][JavaScript][C#][ASP.NET][WebForm] 主版頁面 Master Page 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗 (目前推薦)
https://shaurong.blogspot.com/2020/11/javascriptcaspnetwebform-master-page.html

[研究][JavaScript] 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-idle-timerjs-session-time.html

[研究][JavaScript][C#][ASP.NET][WenForm] 主版頁面 Master Page 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascriptcaspnetwenform-master-page.html

[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-timeout-dialogjs-session.html

[研究][C#][ASP.NET][WebForm] Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-sessionn-time-out.html

[研究][C#][ASP.NET][WebForm] Master Page 的 Sessionn Time Out 自動登出前倒數計時 (目前推薦)
http://shaurong.blogspot.com/2020/11/caspnetwebform-master-page-sessionn.html

[研究][C#][ASP.NET][WebForm][JavaScript]顯示 Web.Config 設定 Session Out Time 時間
http://shaurong.blogspot.com/2020/11/caspnetwebformjavascript-webconfig.html


[研究][JavaScript] 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗

[研究][JavaScript] 用 idle-timer.js ( jQuery Idle Timer Plugin v1.1.1  2020-06-25 版) 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗

2020-11-17

環境 Visual Studio 2019 v16.8.1 版 + C# + ASP.NET  + WebForm 

NuGet 要安裝數個套件,jQuery, BootStrap, popper, moment,不確定是否可缺。

敝人測試用 BootStrap 3.5.1 或 4.x 都可以用。

jQuery Idle Timer Plugin 要手動下載,把 idle-timer.js 拿過來用 ( 一個檔案就好)

https://github.com/thorst/jquery-idletimer


Download

Compressed ~3kb

https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js

Uncompressed ~11kb

https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.js

不要下載 src 目錄下的 idle-timer.js,那個不是。


根據下面網址,jQuery Idle Timer Plugin 目前為 v1.1.1 2020-06-25 版

https://raw.githubusercontent.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js


Default.aspx


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication9.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <%--相依性可能影響順序先後,但這個順序可用--%>
    <script src="Scripts/jquery-3.5.1.js"></script>
    <script src="Scripts/idle-timer.js"></script>
    <link href="Content/bootstrap.css" rel="stylesheet" />
    <script src="Scripts/popper.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/moment.js"></script>
</head>
<body>
    <form id="form1" runat="server">
        
        <div class="container">
            <h2>Concept</h2>
            <p>
                Wait 10 seconds, you will see a expiring warning. Wait 10 more seconds and you will see that you have been logged out.
       
            </p>
            
        </div>
        <div class="modal fade" id="mdlExpirationWarning" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">Session Expiration Warning</h5>

                    </div>
                    <div class="modal-body">
                        <p>You've been inactive for a while. For your security, we'll log you out automatically. Click "Stay Online" to continue your session. </p>
                        <p>
                            Your session will expire in <span class="bold" id="sessionSecondsRemaining">120</span> seconds.
                   
                        </p>
                    </div>
                    <div class="modal-footer">
                        <button id="extendSession" type="button" class="btn btn-primary" data-dismiss="modal">
                            Stay
                        Online</button>
                        <button id="logoutSession" type="button" class="btn btn-secondary">Logout</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="modal fade" id="mdlLoggedOut" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">You have been logged out</h5>
                    </div>
                    <div class="modal-body">
                        <p>Your session has expired.</p>
                    </div>
                </div>
            </div>
        </div>
    </form>

    <script>
        // You could pull this out to its own file very easily
        window.app = window.app || {};

        app.session = {

            //Settings
            warningTimeout: 10000, //(ms) The time we give them to say they want to stay signed in
            inactiveTimeout: 20000, //(ms) The time until we display a warning message
            minWarning: 5000, //(ms) If they come back to page (on mobile), The minumum amount, before we just log them out
            timerSyncId: "SomethingUnique", //The key idleTimer will use to write to localStorage
            logoutUrl: "/logout", //Your url to log out, if you want you could build the url to pass a referal param
            keepAliveUrl: "api/user/KeepAlive", // The url for the keepalive api
            keepaliveInterval: 5000, //(ms) the interval to call keep alive url
            //From here down you shouldnt have to alter anything
            warningStart: null, //Date time the warning was started
            warningTimer: null, //Timer running every second to countdown to logout
            keepaliveTimer: null, //Timer for independent ping to keep session alive
            logout: function () {
                //Write to storage to tell other tab its time to sign out
                if (typeof (localStorage) !== "undefined") {
                    localStorage.setItem(app.session.timerSyncId, 0);
                }

                //Send this page to the logout url, that will destroy session and forward to login
                //window.location = app.session.logoutUrl;

                //To simulate logout we are just showing the logout dialog and locking the screen
                $("#mdlExpirationWarning").modal("hide");
                $("#mdlLoggedOut").modal("show");
            },
            keepAlive: function () {
                //Hide logout modal
                $("#mdlExpirationWarning").modal("hide");

                //Clear the timer
                clearTimeout(app.session.warningTimer);
                app.session.warningTimer = null;

                //Restart the idleTimer
                $(document).idleTimer("reset");
            },
            startKeepAliveTimer: function () {
                // Basically I just poll the server half way through the session life
                // to make sure the servers session stays valid
                clearTimeout(app.session.keepaliveTimer);
                app.session.keepaliveTimer = setInterval(function () {
                    app.session.sendKeepAlive();
                }, (app.session.inactiveTimeout / 2));
            },
            sendKeepAlive: function () {
                // Write a new date to storage so any other tabs are informed that this tab
                //  sent the keepalive
                if (typeof (localStorage) !== "undefined") {
                    localStorage.setItem(app.session.timerSyncId + "_keepalive", +new Date());
                }

                // The actual call to the keep alive api
                //$.post(app.session.keepAliveUrl).fail(function (jqXHR) {
                //    if (jqXHR.status == 500 || jqXHR.status == 0) {
                //        app.session.logout();
                //    }
                //});
            },
            showWarning: function (obj) {
                //Get time when user was last active
                var diff = (+new Date()) - obj.lastActive - obj.timeout,
                    warning = (+new Date()) - diff;

                // Destroy idleTimer so users are forced to click the extend button
                $(document).idleTimer("pause");

                //On mobile js is paused, so see if this was triggered while we were sleeping
                if (diff >= app.session.warningTimeout || warning <= app.session.minWarning) {
                    app.session.logout();
                } else {

                    //Show dialog, and note the time
                    $('#sessionSecondsRemaining').html(Math.round((app.session.warningTimeout - diff) / 1000));
                    $("#mdlExpirationWarning").modal("show");
                    app.session.warningStart = (+new Date()) - diff;

                    //Update counter downer every second
                    app.session.warningTimer = setInterval(function () {
                        var remaining = Math.round((app.session.warningTimeout / 1000) - (((+new Date()) - app.session.warningStart) / 1000));

                        if (remaining >= 0) {
                            $('#sessionSecondsRemaining').html(remaining);
                        } else {
                            app.session.logout();
                        }
                    }, 1000)
                }
            },
            localWrite: function (e) {

                if (typeof (localStorage) !== "undefined" && e.originalEvent.key == app.session.timerSyncId && app.session.warningTimer != null) {
                    // If another tab has written to cache then
                    if (e.originalEvent.newValue == 0) {
                        // If they wrote a 0 that means they chose to logout when prompted
                        app.session.logout();
                    } else {
                        // They chose to stay online, so hide the dialog
                        app.session.keepAlive();
                    }

                } else if (typeof (localStorage) !== "undefined" && e.originalEvent.key == app.session.timerSyncId + "_keepalive") {
                    // If the other tab sent a keepAlive poll to the server, reset the time here so we dont send two updates
                    // This isnt really needed per se but it will save some server load
                    app.session.startKeepAliveTimer();
                }
            }
        };

        $(function () {
            //This will fire at X after page load, to show an inactive warning
            $(document).on("idle.idleTimer", function (event, elem, obj) {
                app.session.showWarning(obj);
            });

            //Create a timer to keep server session alive, independent of idleTimer
            app.session.startKeepAliveTimer();

            //User clicked ok to extend session
            $("#extendSession").click(function () {
                app.session.keepAlive(); //Remove the warning dialog etc
            });

            //User clicked logout
            $("#logoutSession").click(function () {
                app.session.logout();
            });

            //Set up the idleTimer, if inactive for X seconds log them out
            $(document).idleTimer({
                timeout: app.session.inactiveTimeout - app.session.warningTimeout,
                timerSyncId: app.session.timerSyncId
            });

            // Monitor writes by other tabs
            $(window).bind("storage", app.session.localWrite);
        });
    </script>
</body>
</html>



Default.aspx.cs  (不用特別去修改)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

Web.Config (預設 20 分鐘,可以不用特別去設定)

<configuration>
  <system.web>
    <sessionState timeout="20"></sessionState>
  </system.web>
</configuration>

(下圖)執行結果,等10秒就會出現



「Stay Online」按鈕按下去,會再多 10 秒可用。
按下 Logout 或不按,最後會跳出

Stay Online 按鈕 (斷成2行) 和訊息文字 是寫在 .aspx 中,而不是 idle-timer.js 中,訊息換成中文字應該沒問題。

如果真的要按鈕後轉址,要再手動修改 logoutUrl 的值,以及相關程式 (預設註解掉)。

//window.location = app.session.logoutUrl;
改成
window.location = app.session.logoutUrl;
實際測試,對話盒視窗跳出後不動它,確實會自動轉址到 logoutUrl 指定的網址。
但是從按下按鈕到轉址發生,需要數秒鐘,有些慢。

keepAliveUrl 實際測試好像不會轉址,或我不會用。

********************************************************************************
2020-11-19 套用到某個系統後,結果不能用,不會跳出對話盒視窗,也沒錯誤訊息。
在 Visual Studio 2019 環境執行,會出現

行: 4055
錯誤: 物件沒有支援這個屬性或方法 'idleTimer'



<script src="Scripts/moment.js"></script>
之後再加上一行 (等於 jQuery 載入2次)
<script src="Scripts/jquery-3.5.1.js"></script>
測試結果錯誤訊息相同為
錯誤: 物件沒有支援這個屬性或方法 'idleTimer'

(完)

相關

[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-timeout-dialogjs-session.html

[研究][C#][ASP.NET][WebForm] Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-sessionn-time-out.html

[研究][C#][ASP.NET][WebForm] Master Page 的 Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-master-page-sessionn.html


2020年11月17日 星期二

[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗

[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗

2020-11-17

環境 Visual Studio 2019 v16.8.1 版 + C# + ASP.NET  + WebForm + jQuery + jQuery UI + timeout-dialog.js

jQuery 和 jQuery UI 可用 NuGet 安裝

其中 timeout-dialog.js 只能手動下載安裝。

https://github.com/rigoneri/timeout-dialog.js


Default.aspx

測試兩個小範例,1個是網頁載入後,Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗。

另一個範例,Click 一個超連結,會跳出 60 秒自動彈出倒數計時對話盒視窗。


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication8.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <%--<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>--%>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <%--<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/jquery-ui.min.js"></script>--%>

    <%--不可用,畫面會走樣--%>
    <%--<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">--%>

    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

    <%--去網站 https://github.com/rigoneri/timeout-dialog.js 下載套件--%>
    <script src="Scripts/timeout-dialog/js/timeout-dialog.js"></script>
    <link href="Scripts/timeout-dialog/css/index.css" rel="stylesheet" />
    <link href="Scripts/timeout-dialog/css/timeout-dialog.css" rel="stylesheet" />
    <%--    
    <link rel="stylesheet" href="css/index.css" type="text/css" media="screen, projection" />
    <link rel="stylesheet" href="css/timeout-dialog.css" type="text/css" media="screen, projection" />
    --%>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <a href="#" id="timeout-example">Click Here to See Demo</a>
        </div>
    </form>
    <script type="text/javascript">
        var SessiontimeLeft = <%= Session.Timeout * 60 %>;
        ////https://rigoneri.github.io/timeout-dialog.js/
        //timeout	number	1200	The number of your session timeout(in seconds).The timeout value minus the countdown value determines how long until the dialog appears.
        //countdown	number	60	The countdown total value(in seconds).
        $(document).ready(function () {
            SessiontimeLeft = 70;   // 網頁載入完成後,Session Time 為 70 sec
            // 剩下 60 秒開始跳出對話盒視窗,進行倒數 (所以網頁載入 70-60=10 開始跳出對話盒視窗)
            $.timeoutDialog({ timeout: SessiontimeLeft, countdown: 60, logout_redirect_url: '../sessionLogout.htm', restart_on_yes: false });
            //$.timeoutDialog({ timeout: 1, countdown: 60, logout_redirect_url: 'https://github.com/rigoneri/timeout-dialog.js', restart_on_yes: false });
        });
    </script>
    <script type="text/javascript">
        /*<![CDATA[*/
        $(function () {
            $("#timeout-example").click(function (e) {
                e.preventDefault();
                $.timeoutDialog({ timeout: 1, countdown: 60, logout_redirect_url: 'https://github.com/rigoneri/timeout-dialog.js', restart_on_yes: false });
            });
        });
/*]]>*/
</script>

</body>
</html>


SessiontimeLeft = 70;  若拿掉,則根據下面這行

var SessiontimeLeft = <%= Session.Timeout * 60 %>;

SessiontimeLeft = 20*60 = 1200 秒 (20 分鐘)

Default.aspx.cs  (不用特別去修改)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

Web.Config (預設 20 分鐘,可以不用特別去設定)

<configuration>
  <system.web>
    <sessionState timeout="20"></sessionState>
  </system.web>
</configuration>

(下圖)執行結果,等10秒就會出現



(下圖) 缺 jQuery UI 執行結果,不會出現對話盒,60 秒也不會倒數,也不會出現任何錯誤訊息。
(下圖) 缺 jQuery 執行結果,不會出現對話盒,訊息也不出現,也不會出現任何錯誤訊息。
********************************************************************************
2020-11-19
視窗彈出後,不管按下 Yes, Keep me signed in 或 No, Sign ne out 或倒數至 0秒,都會出現錯誤。

https://github.com/rigoneri/timeout-dialog.js/blob/master/js/timeout-dialog.js

顯示 timeout-dialog.js v1.0.1, 01-03-2012,已經多年沒有改版了。

(完)

相關

[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-timeout-dialogjs-session.html

[研究][C#][ASP.NET][WebForm] Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-sessionn-time-out.html

[研究][C#][ASP.NET][WebForm] Master Page 的 Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-master-page-sessionn.html



[研究][C#][ASP.NET][WebForm] Master Page 的 Session Time Out 自動登出前倒數計時

[研究][C#][ASP.NET][WebForm] Master Page 的 Session Time Out 自動登出前倒數計時

2020-11-17

續這篇

[研究][C#][ASP.NET][WebForm] Session Time Out 自動登出前倒數計時

http://shaurong.blogspot.com/2020/11/caspnetwebform-session-time-out.html


測試工具 Visual Studio 2019 v16.8.1 版

Site1.Master


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="WebApplication1.Site1" %>

<!DOCTYPE html>

<html>
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <%--https://docs.microsoft.com/zh-tw/dotnet/api/system.web.ui.timer?view=netframework-4.8--%>
            <%--https://docs.microsoft.com/zh-tw/dotnet/api/system.web.sessionstate.httpsessionstate.timeout?view=netframework-4.8--%>
            <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
            <%--Interval="1000" 是每1秒觸發一次--%>
            <asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick"></asp:Timer>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Button ID="Button_Timer" runat="server" BackColor="LightGreen" Height="40px" Width="100px" Style="border-radius: 8px" />
                </ContentTemplate>
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="tick" />
                </Triggers>
            </asp:UpdatePanel>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
    </form>
</body>
</html>


Site1.Master.cs



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Site1 : System.Web.UI.MasterPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // --------------------------------------------------------------------------------
            // 顯示 Session Time Out 時間 (Begin)
            int timeout = System.Web.HttpContext.Current.Session.Timeout;

            // 設定 Session Time Out 時間 20 分鐘
            //if (!ScriptManager1.IsInAsyncPostBack)    // Fail, 當 ScriptManager1 在 MasterPage 時候不能這樣存取
            //if (!Master.ScriptManager1.IsInAsyncPostBack)    // Fail
            //if (!this.Master.FindControl("ScriptManager1").IsInAsyncPostBack) // Fail
            ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
            if (!scriptManager.IsInAsyncPostBack)
            {
                // 把目前的時間,加上 Session Time Out 設定值,
                //Session["timeout"] = DateTime.Now.AddMinutes(20).ToString();
                Session["timeout"] = DateTime.Now.AddMinutes(timeout).ToString();
            }
            // 顯示 Session Time Out 時間 (End)
            // --------------------------------------------------------------------------------
        }
        protected void Timer1_Tick(object sender, EventArgs e)
        {
            if (0 > DateTime.Compare(DateTime.Now,
                DateTime.Parse(Session["timeout"].ToString())))
            {
                Button_Timer.Text = ((Int32)DateTime.Parse(Session["timeout"].
                    ToString()).Subtract(DateTime.Now).Minutes).ToString()
                    + ":" +
                    ((Int32)DateTime.Parse(Session["timeout"].
                    ToString()).Subtract(DateTime.Now).Seconds).ToString();
            }
        }
    }
}

重點是使用 Master Page 時候, Site1.Master 中,

if (!ScriptManager1.IsInAsyncPostBack)

要改成

ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);

if (!scriptManager.IsInAsyncPostBack)

才行。


Default.aspx (不用特別去修改)


<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>

Default.aspx.cs  (不用特別去修改)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

Web.Config (預設 20 分鐘,可以不用特別去設定)

<configuration>
  <system.web>
    <sessionState timeout="20"></sessionState>
  </system.web>
</configuration>

(完)

相關

[研究] AjaxControlToolkit ToolkitScriptManager 元素不是已知元素
http://shaurong.blogspot.com/2020/11/ajaxcontroltoolkit-toolkitscriptmanager.html

[研究][JavaScript][C#][ASP.NET][WebForm] 主版頁面 Master Page 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗 (目前推薦)
https://shaurong.blogspot.com/2020/11/javascriptcaspnetwebform-master-page.html

[研究][JavaScript] 用 idle-timer.js 做 Session Time Out 前 N 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-idle-timerjs-session-time.html

[研究][JavaScript][C#][ASP.NET][WenForm] 主版頁面 Master Page 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascriptcaspnetwenform-master-page.html

[研究][JavaScript] 用 timeout-dialog.js 做 Session Time Out 前 60 秒自動彈出倒數計時對話盒視窗
http://shaurong.blogspot.com/2020/11/javascript-timeout-dialogjs-session.html

[研究][C#][ASP.NET][WebForm] Sessionn Time Out 自動登出前倒數計時
http://shaurong.blogspot.com/2020/11/caspnetwebform-sessionn-time-out.html

[研究][C#][ASP.NET][WebForm] Master Page 的 Sessionn Time Out 自動登出前倒數計時 (目前推薦)
http://shaurong.blogspot.com/2020/11/caspnetwebform-master-page-sessionn.html

[研究][C#][ASP.NET][WebForm][JavaScript]顯示 Web.Config 設定 Session Out Time 時間
http://shaurong.blogspot.com/2020/11/caspnetwebformjavascript-webconfig.html



[研究][C#][ASP.NET][WebForm][JavaScript]顯示 Web.Config 設定 Session Out Time 時間

[研究][C#][ASP.NET][WebForm][JavaScript]顯示 Web.Config 設定 Session Out Time 時間

2020-11-17

載入網頁時,顯示 Web.Config 設定 Session Time 時間。

參考下面修改,但有些 Code 不能用

Alert Session Time out in ASP.NET
https://www.codeproject.com/Articles/227382/Alert-Session-Time-out-in-ASP-Net

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script language="javascript" type="text/javascript">
        //https://www.codeproject.com/Articles/227382/Alert-Session-Time-out-in-ASP-Net
        //This method is obsolete, it has been replaced by System.Configuration!System.Configuration.ConfigurationManager.AppSettings
        <%--var sessionTimeoutWarning = "<%= System.Configuration.ConfigurationSettings.AppSettings["SessionWarning"].ToString()%>"; /*fail,沒有彈出對話盒*/--%>
        <%--var sessionTimeoutWarning = "<%= System.Configuration.ConfigurationManager.AppSettings["SessionWarning"].ToString()%>";  /*fail,沒有彈出對話盒*/--%>
        //var sessionTimeoutWarning = 1;  /*fail,沒有彈出對話盒*/
        var sessionTimeoutWarning = 0;    /* OK */
        var sessionTimeout = "<%= Session.Timeout %>";

        var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
        setTimeout('SessionWarning()', sTimeout);

        function SessionWarning() {
            var message = "Your session will expire in another " +
                (parseInt(sessionTimeout) - parseInt(sessionTimeoutWarning)) +
                " mins! Please Save the data before the session expires";
            alert(message);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
        </div>
    </form>
</body>
</html>


Default.aspx.cs (不用修改)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    }
}

Web.Config
<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
	<system.web>
		<compilation debug="true" targetFramework="4.7.2"/>
		<httpRuntime targetFramework="4.7.2"/>
	</system.web>
	<appSettings>
		<!--Session Time Out 前1分鐘警告-->
		<add key="SessionWarning" value="1" />
	</appSettings>
	<system.codedom>
		<compilers>
			<compiler language="c#;cs;csharp" extension=".cs"
			  type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
			  warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
			<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
			  type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
			  warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
		</compilers>
	</system.codedom>
</configuration>

這邊有討論此種作法問題

https://www.itdaan.com/tw/e65f06f8610f33f3662810e8dd7b4261

(完)

[研究] 工作排程器 - 執行失敗 0x41303 與 0xE0434352

[研究] 工作排程器 - 執行失敗 0x41303 與 0xE0434352

2020-11-17

Windows Server 2019 工作排程器 - 執行失敗 0x41303 與 0xE0434352

Task Scheduler - Not running 

一個錯誤是 0x41303,另一個錯誤是 0xE0434352,具體問題和解法不詳。






********************************************************************************

記錄檔名稱:         Microsoft-Windows-TaskScheduler/Operational

來源:            Microsoft-Windows-TaskScheduler

日期:            2020/11/17 上午 10:23:47

事件識別碼:         101

工作類別:          工作啟動失敗

層級:            錯誤

關鍵字:           (1)

使用者:           SYSTEM

電腦:            CSCWeb.CSCWebAD.nccst.nat.gov.tw

描述:

工作排程器無法為使用者 "CSCWEBAD\Administrator" 啟動 "\WebSiteCheck" 工作。其他資料: 錯誤值: 2147943726。

事件 Xml:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">

  <System>

    <Provider Name="Microsoft-Windows-TaskScheduler" Guid="{de7b24ea-73c8-4a09-985d-5bdadcfa9017}" />

    <EventID>101</EventID>

    <Version>0</Version>

    <Level>2</Level>

    <Task>101</Task>

    <Opcode>101</Opcode>

    <Keywords>0x8000000000000001</Keywords>

    <TimeCreated SystemTime="2020-11-17T02:23:47.123193100Z" />

    <EventRecordID>97348</EventRecordID>

    <Correlation />

    <Execution ProcessID="1784" ThreadID="2220" />

    <Channel>Microsoft-Windows-TaskScheduler/Operational</Channel>

    <Computer>CSCWeb.CSCWebAD.nccst.nat.gov.tw</Computer>

    <Security UserID="S-1-5-18" />

  </System>

  <EventData Name="TaskStartFailedEvent">

    <Data Name="TaskName">\WebSiteCheck</Data>

    <Data Name="UserContext">CSCWEBAD\Administrator</Data>

    <Data Name="ResultCode">2147943726</Data>

  </EventData>

</Event>

********************************************************************************

(完)

相關

新增混合式設定向導會因錯誤代碼0xe0434352 而崩潰
https://docs.microsoft.com/zh-tw/exchange/troubleshoot/hybrid-configuration-wizard-errors/new-hybrid-configuration-wizard-crashes-with-0xe0434352

修正: 「 例外狀況代碼︰ 0xe0434352 」 錯誤,當您將累積的更新套用到 BizTalk server
https://support.microsoft.com/zh-tw/help/3158684/fix-exception-code-0xe0434352-error-when-you-apply-a-cumulative-update

【茶包射手日記】.NET 排程導致 KERNELBASE.DLL 0xe0434352 錯誤
https://blog.darkthread.net/blog/schtask-kernelbase-dll-error/

電腦又出問題了…這次看來是 .Net Framework 有問題?
https://kheresy.wordpress.com/2015/12/06/system-problem-looks-like-net-crash/


2020年11月16日 星期一

[研究][C#][ASP.NET][WebForm] 依下拉選單數量,動態生成 TextBox 輸入欄位

[研究][C#][ASP.NET][WebForm] 依下拉選單數量,動態生成 TextBox 輸入欄位

2020-11-16

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script>
        function createInputTexts(Xselect) {
            if (Xselect.selectedIndex > 0) {
                var p1 = document.getElementById("p1");
                p1.innerHTML = "";
                var count = parseInt(Xselect.options[Xselect.selectedIndex].value);
                for (var i = 0; i < count; i++)
                    p1.innerHTML = p1.innerHTML + "<input type='text' name='DynaTextBox" + i + "' /><br/>";
                p1.innerHTML = p1.innerHTML + "<input type='hidden' name='textCount' value='" + count + "' />";
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:DropDownList ID="DropDownList1" runat="server" onchange="createInputTexts(this)">
                <asp:ListItem>請選擇…</asp:ListItem>
                <asp:ListItem>1</asp:ListItem>
                <asp:ListItem>2</asp:ListItem>
                <asp:ListItem>3</asp:ListItem>
                <asp:ListItem>4</asp:ListItem>
                <asp:ListItem>5</asp:ListItem>
            </asp:DropDownList>
            <p id="p1"></p>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
        </div>
    </form>
</body>
</html>



Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            if (Request["textCount"] != null)
            {
                int textCount = int.Parse(Request["textCount"]);
                for (int i = 0; i < textCount; i++)
                    Response.Write(Request["DynaTextBox" + i.ToString()] + "<br/>");
            }
        }
    }
}

(完)

相關

Google  "ASP.NET 動態 textBox 值取得"


動態產生的TextBox,如何抓取填入的值?

https://social.msdn.microsoft.com/Forums/zh-TW/89d80ae4-5fef-48a1-a435-9a247f0b5768/2120524907299862998330340textbox652922291420309252352146222635208?forum=236

註:textBox會連在一起,this.Panel1.Controls.Add("<br />"); 不行,因為不是 Control,另外 FindControl 抓值麻煩。