2016年1月29日 星期五

網頁輸入頁面Enter鍵處理元件(KeyDownProcess Version:1.61)


##更新實作模擬Click的方法
function KeyDownProcess(e) {
    //-----------------------------------------------------------
    //網頁親和性輸入控制元件
    //元件功能:可以讓網頁資料的輸入更親切,功能如下:
    //1.按下Enter鍵自動找到下一個可輸入輸入元件
    //2.按下Enter鍵自動找尋submit按鍵,如果找到則模擬Click的功能
    //3.當輸入元件設定唯讀時,按下backspace鍵時,防止網頁轉址
    //4.支援無障礙導覽設定
    //5.支援IE、Firefox、Google Chrome瀏覽器
    //6.支援按下shift鍵全域變數ShiftKeyDown
    //版本:1.61(2016.01.30)
    //作者:科碩資訊有限公司
    //引用本元件,請保留作者和版本資訊
    //連絡mail:cursor@cursorinfo.com.tw
    //------------------------------------------------------------
    w3cEvent = e;
    ShiftKeyDown = false;
    var kv = 0;
    var rv = false;
    var isTextarea = false;
    var currentId = null; //目前元件
    var ex;
    var isAll = typeof (document.all) == "object";
    if (isAll) {
        ShiftKeyDown = event.shiftKey;
        ex = event;
        kv = ex.keyCode;
        isTextarea = (ex.srcElement.tagName == "TEXTAREA");
        currentId = ex.srcElement.id == undefined ? '' : ex.srcElement.id;
    }
    else {
        ShiftKeyDown = e.shiftKey;
        ex = e;
        kv = ex.which * 1;
        isTextarea = (ex.target == "[object HTMLTextAreaElement]");
        currentId = ex.target.id == undefined ? '' : ex.target.id;
    }
    switch (kv) {
        case 13:
            if (isAll) {
                if (ex.srcElement.tagName == "A" || (ex.srcElement.tagName == "INPUT" && ex.srcElement.type == "BUTTON"))
                    return true;
            }
            if ((currentId.length == 0))
                return false;
            if (isTextarea == true) {
                rv = isTextarea;
            }
            else {
                var cts = isAll ? document.all : document.getElementsByTagName('*');
                var cid = "";
                var queryBu = null;
                var beginNext = false; //開始比對是否為輸入元件
                var nextInput = null; //下一個輸入元件
                var specialSubmitId = "textQueryBU"; //指定特例的submit id
                var exceptionSubmitId = "waitting"; //指定例外的submit Id
                for (ii = 0; ii < cts.length; ii++) {
                    if (cts[ii].type == null || cts[ii].id == null)
                        continue;

                    if (cts[ii].id == currentId) {
                        beginNext = true;
                        continue;
                    }
                    if (beginNext == true && (cts[ii].id.indexOf(specialSubmitId) > -1 || ((cts[ii].type == "submit" || cts[ii].type == "image") && cts[ii].id.indexOf(exceptionSubmitId) == -1))) {
                        queryBu = cts[ii]; //找到submit元件
                        break;
                    }
                    else if (beginNext == true && (cts[ii].type == "text" || cts[ii].type == "textarea" || cts[ii].type == "password") && cts[ii].readOnly == false && cts[ii].style.display != "none") {
                        nextInput = cts[ii]; //找到下一個文字輸入元件
                        break;
                    }
                }
                if (null != queryBu) {
                    setTimeout("doClickId('" + queryBu.id + "');", 100);
                    rv = false;
                }
                else if (null != nextInput && nextInput.offsetWidth != 0) {
                    try {
                        nextInput.focus();
                    } catch (Error) { return true; }
                    rv = false;
                }
            }
            break;
case 8:
            if (currentId.length > 0)
                return !document.getElementById(currentId).readOnly;
            else
                return true;
            break;
        default:
            rv = true;
            break;
    }
    return rv;
}

//實做模擬Click的功能
function doClickId(source) {
    var o = document.getElementById(source);
    if (!o.addEventListener) {
        o.attachEvent('onclick', onClick);
    } else {
        o.addEventListener('click', onClick, false);
    }
}

Windows Server 2012 R2 IIS 裝載WCF失敗解決方案


一、問題說明
Windows Communication Foundation (WCF) 是用於建置服務導向應用程式的架構。
ASP.NET可以快速建置WCF服務,讓網站資料傳遞更為輕便,大有取代Web Service的趨勢。
當我們使用Visual Studio建置包含WCF For AJAX的網站後,在本機運作正常,部署到客戶端時,如果連結service.svc發生404的錯誤時,可能是伺服器尚未設定*.svc的處理常式對應
(發生的原因可能是:先安裝WCF再安裝IIS)

二、解決方案:
  A、開啟網際網路資訊服務 (IIS) MMC 嵌入式管理單元
  B、進入處理常式對應,檢查下圖中*.svc的對應設定


 
C、如果沒有上圖中的*.svc對應,就必須手動完成設定,以4.0和64位元作業系統為例:
    1、先設定svc-Integrated-4.0,點選 [新增 Managed 處理常式]
 

要求路徑:*.svc
    類型(T):System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
    名稱(N):svc-Integrated-4.0
    並點選『要求限制』按鈕,取消核取方塊,並點選『確定』完成設定1。

   2、設定svc-ISAPI-4.0_64bit,點選[新增指令碼對應]
 

要求路徑:*.svc
    執行檔(E):%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll
    名稱(N):svc-ISAPI-4.0_64bit
    並點選『要求限制』按鈕,取消核取方塊,並點選『確定』完成設定2。

  D、完成上述的設定後,就可以讓.NETFramework4.0的web應用程式,支援WCF的服務。

三、後記:
  以上說明,希望此備忘錄能幫助使用WCF服務遇到困境的程式開發者解決問題。

32位元4.0的類型:System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
32位元4.0的執行檔:%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll




2015年12月30日 星期三

糟糕!使用NPOI操作Excel文件當機了

NPOI是Apache License 2.0的開放原始碼函式庫,提供.NET程式開發人員在無安裝Microsoft Office的環境下,讀取和操作Office 97-2007文件。

問題說明:

當我們使用CreateSheet方法去創建一組新的工作表,如下面的程式碼:
       HSSFWorkbook Workbook;   
       Workbook = new HSSFWorkbook();
       Workbook.CreateSheet("Sheet1");
       ISheet sheet = Workbook.GetSheetAt(0);

如果使用了下面的方法讀取工作表的row或cell的資料時,
出現嚴重的Exception而無法知道原因!

例如:
                IRow row;
                row = sheet.GetRow(0);
                if (row == null)
                    row = sheet.CreateRow(0);

解決方法:
當工作表使用CreateSheet("Sheet1")方法產生時,不能使用sheet.GetRow(0)的方法,必須直接使用CreateRow(0)的方法;對於Cell的操作也是一樣,否則伺服器會完全當機!

正確的方法如下:
IRow row = sheet.CreateRow(0);
ICell cell = row.CreateCell(0);

※記住了:在NPOI元件下使用CreateSheet()方法產生的工作表,初次操作row或cell時,要直接使用CreateRow或CreateCell,不能習慣性地先讀取row或cell再判斷是否為nll的方式!

2015年9月28日 星期一

實作動態加入AsyncFileUpload Control

●問題描述:
開發ASP.NET網站系統最常使用的檔案上傳元件為:AJAX Control Tool Kit的AsyncFileUpload Control,當實作頁面時可能遇到多資料列需要分別上傳檔案的情況

如果直接在頁面上嵌入很多的AsyncFileUpload Control,並不是王道的作法;本文試著將動態實作多個AsyncFileUpload Control的重點,說明如下:

一、UI頁面布置程式碼:
加入一組 Panel Control 即可

二、動態產生資料頁面如下:
 
三、實作『上傳檔案』按鈕的Click 或Command事件

protected void bu_Command(object sender, CommandEventArgs e)
 {
        Button bu = (Button)sender;
        string id = bu.ID.TrimStart(new char[] { 'b', 'u' });
        uploadHF.Value = id;
        Panel1.Controls.Clear();
        ScriptManager.RegisterStartupScript(Page, Page.GetType(), "reroll", "__doPostBack();", true);

}

四、實作Post Back 後Page Load 動態加入AsyncFileUpload Control

if (string.IsNullOrEmpty(uploadHF.Value) == false)
{

  string id = uploadHF.Value;
  string fid = string.Format("up_{0}", id
);//上傳檔案按鈕的容器ID
  AsyncFileUpload afu = new AsyncFileUpload();
  afu.Width = Unit.Percentage(60);
  afu.ID = "afu" + id;
  afu.UploadedComplete += AsyncFileUpload1_UploadedComplete;
  afu.UploadedFileError += AsyncFileUpload1_UploadedFileError;
  afu.OnClientUploadComplete = "UploadComplete";
  //afu.ThrobberID = im.ID;
  Page.Master.FindControl("ContentPlaceHolder1").FindControl("Panel1").FindControl (fid).Controls.Add(afu);

}

補充說明:此區塊還需要實作
1、AsyncFileUpload1_UploadedComplete
2、AsyncFileUpload1_UploadedFileError
3、UI頁面上的UploadComplete
以上的實作程式碼網路上很多範例這裡不再臚列。

五、完成頁面點選『上傳檔案』示例














※實作重點:必須在Page_Load事件中動態加入AsyncFileUpload Control

2014年12月1日 星期一

網頁輸入頁面Enter鍵處理元件(KeyDownProcess Version:1.6)


##加入按一下shift鍵的全域變數旗標,可實作連選或取消的功能
function KeyDownProcess(e) {
    //-----------------------------------------------------------
    //網頁親和性輸入控制元件
    //元件功能:可以讓網頁資料的輸入更親切,功能如下:
    //1.按下Enter鍵自動找到下一個可輸入輸入元件
    //2.按下Enter鍵自動找尋submit按鍵,如果找到則模擬Click的功能
    //3.當輸入元件設定唯讀時,按下backspace鍵時,防止網頁轉址
    //4.支援無障礙導覽設定
    //5.支援Firefox、Google Chrome瀏覽器
    //6.支援按下shift鍵全域變數ShiftKeyDown
    //版本:1.6(2014.12.01)
    //作者:科碩資訊有限公司
    //引用本元件,請保留作者和版本資訊
    //連絡mail:cursor@cursorinfo.com.tw
    //------------------------------------------------------------
    w3cEvent = e;
    ShiftKeyDown = false;
    var kv = 0;
    var rv = false;
    var isTextarea = false;
    var currentId = null; //目前元件
    var ex;
    var isAll = typeof (document.all) == "object";
    if (isAll) {
        ShiftKeyDown = event.shiftKey;
        ex = event;
        kv = ex.keyCode;
        isTextarea = (ex.srcElement.tagName == "TEXTAREA");
        currentId = ex.srcElement.id == undefined ? '' : ex.srcElement.id;
    }
    else {
        ShiftKeyDown = e.shiftKey;
        ex = e;
        kv = ex.which * 1;
        isTextarea = (ex.target == "[object HTMLTextAreaElement]");
        currentId = ex.target.id == undefined ? '' : ex.target.id;
    }
    switch (kv) {
        case 13:
            if (isAll) {
                if (ex.srcElement.tagName == "A" || (ex.srcElement.tagName == "INPUT" && ex.srcElement.type == "BUTTON"))
                    return true;
            }
            if ((currentId.length == 0))
                return false;
            if (isTextarea == true) {
                rv = isTextarea;
            }
            else {
                var cts = isAll ? document.all : document.getElementsByTagName('*');
                var cid = "";
                var queryBu = null;
                var beginNext = false; //開始比對是否為輸入元件
                var nextInput = null; //下一個輸入元件
                var specialSubmitId = "textQueryBU"; //指定特例的submit id
                var exceptionSubmitId = "waitting"; //指定例外的submit Id
                for (ii = 0; ii < cts.length; ii++) {
                    if (cts[ii].type == null || cts[ii].id == null)
                        continue;

                    if (cts[ii].id == currentId) {
                        beginNext = true;
                        continue;
                    }
                    if (beginNext == true && (cts[ii].id.indexOf(specialSubmitId) > -1 || ((cts[ii].type == "submit" || cts[ii].type == "image") && cts[ii].id.indexOf(exceptionSubmitId) == -1))) {
                        queryBu = cts[ii]; //找到submit元件
                        break;
                    }
                    else if (beginNext == true && (cts[ii].type == "text" || cts[ii].type == "textarea" || cts[ii].type == "password") && cts[ii].readOnly == false && cts[ii].style.display != "none") {
                        nextInput = cts[ii]; //找到下一個文字輸入元件
                        break;
                    }
                }
                if (null != queryBu) {
                    setTimeout("doClickId('" + queryBu.id + "');", 100);
                    rv = false;
                }
                else if (null != nextInput && nextInput.offsetWidth != 0) {
                    try {
                        nextInput.focus();
                    } catch (Error) { return true; }
                    rv = false;
                }
            }
            break;
case 8:
            if (currentId.length > 0)
                return !document.getElementById(currentId).readOnly;
            else
                return true;
            break;
        default:
            rv = true;
            break;
    }
    return rv;
}

//實做模擬Click的功能
function doClickId(source) {
    var o = document.getElementById(source);
    if (document.all && typeof (document.all) == "object") //IE
        o.click();
    else {
        if (document.createEvent) {
            var e = document.createEvent('MouseEvent');
            e.initEvent('click', true, false);
            o.dispatchEvent(e);
        } else {
            o.fireEvent('onclick');
        }
    }
}

2014年3月6日 星期四

如何使用Robocopy複製檔案到一個需要使用新帳號登入的UNC路徑

Robocopy是Windows Server 高速同步備份、複製、移動大量檔案的好工具
有關Robocopy的功能詳細說明與介紹,可參閱下面文章:

Robocopy高速同步備份、複製、移動大量檔案

本文試著解決使用Robocopy複製檔案到UNC路徑時,需要登入不同的使用者帳號和密碼的問題。

備份Windows伺服器的資料到網路儲存設備時,輕便的決方案可以是:使用Windows工作排程器+Robocopy命令

處理步驟:
1、將Robocopy的指令寫成.bat檔,例如:
      robocopy 來源路徑(本機) 目的路徑 /e /xo /purge
     (相關參數功能請參閱 Robocopy高速同步備份、複製、移動大量檔案)

2、將此批次處理檔案加入工作排成器的啟動程式,並設定好相關排程,即可運作。


可能遭遇的問題:
當我想將檔案複製到一個需要使用新帳號登入的UNC路徑時,例如:
robocopy c:\windows \\192.168.1.1\home /e /xo /purge
上面的指令將無法正常被執行。

解決方案如下:
net use \\192.168.1.1\home /u:登入帳號 登入密碼
robocopy c:\windows \\192.168.1.1\home /e /xo /purge
net use \\192.168.1.1\home -D

※此功能只支援網域內的主機或IP位址

2014年2月28日 星期五

使用 OleDb Provider 如何在 SQL Server 存入完整的 DateTime?

一、問題描述:

使用OleDb Provider將日期時間資料存入SQL Server時,最常遇到的問題是:在Datetime資料型別下,只能存入日期,無法存日時間;因此存入的資料變成:2014/02/28 00.00.00

二、解決方案:

可以使用資料庫預設值,取得存入的時間。但是遇到資料修改後,需要自訂存入日期時間,此時又回到原來的困境;如何存檔呢?

一般使用存檔的語法如下:

OleDbParameter objectdate = new OleDbParameter("@objectdate", OleDbType.DBDate); objectdate.Value = DateTime.Now;
cmd.Parameters.Add(objectdate);

解決方法如下:

OleDbParameter objectdate = new OleDbParameter("@objectdate", OleDbType.DBTimeStamp); objectdate.Value = DateTime.Now.ToUniversalTime();
cmd.Parameters.Add(objectdate);

存入資料庫結果:2014/02/28 11:11:11.111
可以存入完整的日期與時間資料。


objectdate.Value = DateTime.Now.ToUniversalTime();
也可以使用自訂格式:
objectdate.Value =string.Format("{0:yyyy/MM/dd HH:mm:ss.fff}",DateTime.Now);
或是:
objectdate.Value =DateTime.NowToString();