Pages

2016-05-25

MVC Razor迴圈分組顯示

在MVC Views (*.cshtml)裏要將一個資料集合作loop迴圈分組顯示,一般正規的Razor程式寫法如下圖:

Rzaor Regular Grouping

應用在Table裏,它就可以輸出下圖行列的分組效果。

Razor Regular Output

但是一個View裏可能會存在多個群組顯示,若每個區塊都放上述的Razor源碼,不僅容易變數衝突,也缺乏程式ReUse的精神,所以我們可以利用C# Action Delegate把需要客制化的部分抽取出來,下圖函式內部裏的StringBuilder可以省略掉,以適應更多的變化:

Action Method

日後在Razor View裏,就可以輕易輸出Grouping HTML自訂字串了。
Razor Custom Grouping

MVC最主要精神就是不要在View裏寫複雜的邏輯程式判斷,應該要將這些分組寫法放到Model去,再包一層Method來簡化呈現參數,例如只提供群組數量就好。

2016-05-18

ASP.NET MVC的執行亂碼訊息

在使用VS2015開發ASP.NET MVC5 Web Application時,若要一步步偵錯當然是執行Debug模式,但它的執行速度比較慢,而且進入點不好控制。所以若很複雜的偵錯,我通常直接使用Release模式(Ctrl+F5)來測跑結果,有錯誤訊息再修改就好。畢竟程序寫久有經驗了,通常只是打錯字而己。

我的習慣是修改後,直接在View的頁面(*.cshtml)視窗按滑鼠右鍵,選擇「View in Browser」來作執行測試:

View in Browser

當cs源碼裏執行有錯誤時,卻發現它出現是亂碼,即使在Web.config設定<customErrors>也無法正常顯示錯誤訊息。偶然一次機會裏,在執行jQuery AJAX存取某頁面View時,我發現在js裏可以讀出正常編碼。

因此我安裝Chrome Postman這個套件,使用GET方式貼上測試頁面的網址(下圖編號2),即可產生正確的錯誤訊息。從此,這樣的方式就是我慣用的MVC專案除錯模式了。

Chrome Postman

在ASP.NET 4.6.1的MVC5 「Web Application」裏,每當異動了cs程式碼,均需重新Build Project,沒有「Website」專案自動編譯的方便功能,可惜MVC5並不完整支援Website專案。值得慶幸的是,WebApp正佈網站時,日後的cs異動只需要直接覆蓋主要的DLL即可,不需要像Website須重新Publish,算是功過相抵能接受。

2016-05-11

使用Docker執行本機端Mono程序

Docker 和傳統虛擬化方式的不同之處,在於少了Guest OS這層,除了大幅減少磁碟空間,最重要是獲得本機的執行效能,直接使用本地主機的作業系統。詳細介可,可閱讀這份教學文件
Docker vs VM

一般而言,我們會在Docker Container虛擬環境中運行獨立服務,透過IP Port對映與外界Host溝通互動。在VMware裏有個Unity功能,可以把Guest VM虛擬環境下的視窗,拉到外面Host運行,感覺就像Host執行一個視窗程式一樣。

Docker也可以透過共用目錄(Docker Volume)讓Host與Guest VM共用同一個資料夾,讓Guest VM去執行共用的程式碼,產生最後結果,再以TTY Console回報至Host,宛如是在本地Host端執行程序一樣。

以下是示範步驟:

  1. 在Ubuntu Linux下安裝Docker:
    # apt-get install docker.io
    約45.4MB
    # docker -v
    Docker version 1.10.3, build 20f81dd
  2. 到Docker Hub尋找官方mono image:

    下載官方mono映像檔image:
    # docker pull mono
    Pull Mono Image
    查看該image資訊
    # docker images
    Docker Images
  3. 在建立mono container之前,我們先建立一個host與container共用目錄(Docker Volume)。
    # mkdir /opt/hello
    建立host本地目錄,應用程式依常規放在/opt/下面(相當Windows的C:\Program Files\XXX)。

    # nano /opt/hello/hello.cs
    建立主程式CS源碼。
    Hello SourceCode
  4. 建立以mono image為主的container, 並掛載/opt/hello這個分享共用目錄。
    # docker run --name mono_container -v /opt/hello:/opt/hello -d -i -t mono /bin/bash
    --name: 命名該container名稱
    -v: 建立分享Volume目錄,指定目錄的對應關係 host_path:container_path
    -d: 該Container以Daemon方式運行,避免建立container時初始狀態為Exited。
    - i –t: 以-i (Interactive)互動方式及獲取-t (TTY)運行container中的/bin/bash環境。
    mono: 指定Image name或ID.
    Container Run
    使用 docker ps -a查詢目前container狀態,此container(mono_container)虛擬環境正在運行中。
  5. 日後要呼叫此container下的虛擬環境及服務,只需要在Host本機輸入docker exec指令即可。
    # docker exec mono_container mono -V
    查詢container下的mono版本資訊
    Mono Version

    因此,編譯及執行Host端的/opt/hello/hello.cs源碼檔,意義和修改Guest VM端裏的檔案是同一份的。
    # docker exec mono_container mcs /opt/hello/hello.cs
    它會編譯hello.cs,並產生hello.exe這個IL檔。
    Docker Exec

    日後在host環境,要執行NET程式,使用以下指令即可:
    # docker exec mono_container mono /opt/hello/hello.exe
    Docker Mono
  6. 若主機reboot重開機,該docker container不會自動運行,可加入rc.local自動運行:
    # vi /etc/rc.local
    加入此行指令即可。
    docker start mono_container

2016-05-04

LINQPad Command Script自動化

我使用LINQPad不是用來查LINQ或SQL,而是把它當作程式產生器,增加編程的工作效率。後來發現它有提供Command-Line的執行模式(lqrun.exe),可以讓伺服器主動透過Schedule排程,定期自動執行一些管理工作,例如每日備份資料庫,FTP上傳到異地備援主機,並刪除超過30天前的舊檔案。你不再需要學習語法難用的Batch File或其他Shell Script,單單純純地執行C# Script即可。

LINQPad免費版本在執行階段沒什麼限制,放在伺服器端跑Task Scheduler批次工作,十分完美搭配。

"C:\LINQPad\lprun.exe" "C:\Task\hello.linq"

Task Scheduler Action

關於更多LINQPad內建功能,請詳見以下連結:

LINQPad Command-Line and Scripting
http://www.linqpad.net/lprun.aspx

LINQPad Extension Methods - Stack Overflow
http://stackoverflow.com/questions/3555317/linqpad-extension-methods