使用PowerShell動態建立C#物件進行FTPS檔案上傳
早先在 PowerShell 以 Posh-SSH 模組開發了 SFTP 站台的檔案上傳腳本。需求又新增 FTPS 站台的檔案上傳支援。找了一下 PowerShell Gallery 比較多人使用的是 PSFTP 模組,測試了一下,發現大部分都是支援 FTP 與 SFTP,沒有直接支援 FTPS 的。沒有,那我們就直接在 PowerShell 裡刻一個吧。
早先在 PowerShell 以 Posh-SSH 模組開發了 SFTP 站台的檔案上傳腳本。需求又新增 FTPS 站台的檔案上傳支援。找了一下 PowerShell Gallery 比較多人使用的是 PSFTP 模組,測試了一下,發現大部分都是支援 FTP 與 SFTP,沒有直接支援 FTPS 的。沒有,那我們就直接在 PowerShell 裡刻一個吧。
目前專案維持舊專案 .NET Framework 與新專案 .NET Core 的關係,而 .NET Framework 專案從 4.5.x、4.6.x、4.7.x、4.8 都有,而伺服器需要安裝至對應版本 .NET Framework,例如,專案使用 .NET Framework 4.7.2,伺服器只安裝 4.7.1 則不行。在維護伺服器時需要確認目前已經安裝的 .NET Framework 版本,微軟官方:「判斷安裝的 .NET Framework 版本」是用 C# 方式去判斷。這在伺服器就是不方便,又不是開發機,我按文件邏輯改為 PowerShell 版本,PowerShell 方法在任何主機都能快速判斷已安裝 .NET Framework 4.5.x ~ 4.8 版本。
在將一個 ASP.NET Web API 應用程式進行容器化(Containerization)發現一個問題,原先的 Web API 部署至 IIS 應用程式之下,我們會區分開發區(Develop)、測試區(Staging)、正式區(Production),而原始的請求因為 IIS 應用程式的關係,路由都會被加上應用程式的前綴(Route Prefix),例如:
要將 ASP.NET MVC / ASP.NET Web API 轉移至 Docker Container 中運行,看似麻煩,但其實非常簡單。以下討論不使用工具與使用 Visual Studio for Docker 工具來達成轉移的工作。
這是一篇有感而發的短文。
最近又在做效能調教的工作,在單一個專案內我移除了近30個無用的NuGet套件。其實不用問,一眼就能看出,這是一個從預設專案範本開始寫的專案。用專案範本有錯嗎?嗯,沒錯,也有錯。原因,最後在說。我們先來看看之前 twMVC#22分享主題:「一個微信專案從0到000的效能調教」的幾張投影片。
專案升級套件後,Web、API相繼掛點,出現黃白畫面:
Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
你是否有過邊看 MSDN Library 文件,不時浮現一個「x」字,心想:「這是在寫什麼鬼?」(台語)的疑問。
.NET 開發人員,你一定讀過 MSDN Library,早些年,MSDN Library 可說是 .NET 開發人員最好的朋友。但近年來,大量的機器翻譯,讓 MSDN Library 品質直線下降。其實,各位所提交的建議,原有一群義工人士,是"真"人工審核。後來不為何,義工人士不斷消失。小弟有幸加入這個消失中的義工團,就我而言,審核分專業和非專業,我不可能專精整個 MSDN Library 技術,在審核非專業內容時需要大量的時間。由於下班後時間有限,只能慢慢放低義工時間,最後,好像能瞭解,機器人造成大量的品質不良,要靠少數幾個人來改善是有難度的。
目前微軟新版文件庫叫 Microsoft Docs,這一個以開源為導向的文件庫,所有文件內容都開源開放在 Github 上,目前繁體中文化正在火熱進行中(但目前還有很大比例,你點擊後還是看到英文內容),既然開源開放,那麼只要你有心,人人都能成為Microsoft Docs繁體中文貢獻者。目前有二種途徑可以參與:
近期不知道有何原因,公司與家中筆電都會不時出現風扇提高轉速的聲音,本來不太在意,但高轉速有時持續一整天,而且電腦明顯變慢,開啟[工作管理員]查看,非常明顯,有個 .NET Runtime Optimization Service(mscorsvw.exe) 長時間在使用 CPU。
公司有個特別的 D 系統,我們需要透過 ASP.NET Web API 去存取它的 XML Web Service 來提供資源。這個 D 系統本身有個特別的限制,就是存取之前使用者需要先進行頁面 Login,然後才能存取 XML Web Service。Login 頁面很單純,就是一個帳號與密碼的組合,沒有其他特別驗證碼等保護。也就是使用者使用者輸入帳號密碼,而 ASP.NET Web API 透過使用者提供的帳號密碼透過程式方式進行登入,我們開發的 ASP.NET Web API 服務從一開始的 Beta 至 RC,這部分的程式碼都沒什麼問題,直到那令人鬼打牆的關鍵人物(暫稱他苦命的呆伯特好了)出現。
簡單說明一下,此 ASP.NET Web API 服務主要使用者在美國,美國下班台灣上班的黃金交接點,我們私下請呆伯特(美國)幫忙測試此 ASP.NET Web API 服務的同事,但幾星期以來僅呆伯特都一直反應無法 Login 服務,由日誌看出來,他確實是登入失敗。但所有幫忙測試的人員只有呆伯特會出現此狀況。D 系統我們無任何權限,我們能做的也只是不斷調整 ASP.NET Web API 程式並不斷請呆伯特幫忙 Login 與測試。但每每得到"不行"時,心情都低落到不行(測到呆伯特都生氣了),不過最後得到一條重要資訊,呆伯特的密碼含有數個的特殊符號。
我們為加解密演算法補上特殊符號的測試程式碼,先確保特殊符號在加密與解密過程正常。其中小心\與"這兩個符號,在C#的字串中,需要使用\\與\"進行轉義。
以這條線索測試到最後終於有了曙光。
Timestamp(中文稱時戳、時間戳)是經常用於安全保護上的一種機制,例如每天上下班的打卡,就是一種保護勞資雙方的機制,卡打下去的那一刻的時間點是無法被偽造,用計算工時與工資。在網站資訊安全方面,例如近年流行的OAuth認證機制(facebook登入、google登入、github登入、Microsoft account登入…等第三方登入機制)中重要的Token,通常就會帶有Timestamp機制,以驗證Token的時效性。
TimeStamp很好,但他的格式並不好處理,我們看一下wiki上的範例:
- Tue 01-01-2009 6:00
- 2005-10-30 T 10:45 UTC
- 2007-11-09 T 11:20 UTC
- Sat Jul 23 02:16:57 2005
- 12569537329
- (1969-07-21 T 02:56 UTC) – first footstep on the Moon, "That's one small step for man, one giant leap for mankind"
- 07:38, 11 December 2012 (UTC)
TimeStamp格式那麼多之外,在多國語系下,你可能還要自行先轉換為UTC (格林威治標準時間)時間。
在上述格式中,我們特別注意到一個12569537329數值,這是什麼東西?這種格式稱Unix Time,它是一種把時間轉換為數值的方式,它以1970-01-01 T 00:00 UTC為基準,每秒加 1 方式計算,如果是在基準點之前,就每秒 -1 方式計算。例如,我們把上述 Unix Time 放到http://www.unixtimestamp.com/進行轉換:
就能還原成特定的時間點。因為數值的特性直覺、簡單、好處理,所以 Unix time 常被拿來做 Timestamp 使用。
早上升級專案 AutoMapper 套件到最新版(4.1.1)後,發現專案無法通過編譯,查看錯誤訊息,看來是 AutoMapper 4.1.1 的屬性有些改變。
錯吳訊息
'xxx.ProfileName': cannot override inherited member 'Profile.ProfileName' because it is not marked virtual, abstract, or override
很明顯,新版本改變了 ProfileName 的存取方式,查詢AutoMapper Releases沒查到什麼有用的資訊。
按下F12查詢 Profile 類別的定義:
ProfileName
屬性僅能 get
,再看看建構式,解法很明顯了:
System.Web.Helpers命名空間是.NET Framework裡一個神秘的組織,它和ASP.NET MVC 3一起推出,知道和用它的人並不多,它暗地裡提供許多便利型的功能(可以參考之前寫的系列文(1、2、3、4、5、6、7、8)。但如上圖所見,它在我VS2015裡的新專案裡就這樣赤裸裸的爆開,開啟著另一個VS2013的專案,怎麼一切安然無事。當下會很直覺的想罵聲-暗,是不是命中帶ㄕㄞˋ,老是碰到這種鬼錯誤。但有幾次VS2015的經驗,我改變心態,耐著性子一路追下去,意外發現System.Web.Helper一件不為人知的故事。
ASP.NET Web API Client Library(HttpClient)讓我們簡單地在.NET用戶端應用程式中與RESTful HTTP Service互動。之前版本的Web API Client Library對於跨平台的支援度不是那麼好,目前Web API Client Library的下一個預覽版已經在這方面進行改良。此預覽版新增了可攜式類別庫(Portable Library)的支援,目前支援.NET Framework 4.5、Windows Store、Windows Phone 8三種應用程式類別。這些支援建構在最近發佈的可攜式HTTPClient和可攜式類別庫支援Json.NET。這樣我們就能建立單一的可攜式類別庫去讓Windows Store App、Windows Phone去呼叫Web API。
接下來,我們要建立三個專案,一個可攜式類別庫,透過可攜式類別庫使用Web API Client Library來呼叫RESTful HTTP Service,一個.NET Framework 4.5的主控台應用程式,一個Windows Store App,主控台應用程式與Windows Store App會透過可攜式類別庫來進行服務呼叫。
這是因為ASP.NET Web API Client Library不支援 xbox 360、Silverlight和Windows Phone 7.5。以下範例不進行Windows Phone 8示範,不過我們的建立的可攜式類別庫是可以支援Windows Phone 8。
這裡可能會出現要求取得市集開發者授權請求,請依畫面登入取得。
以下資訊均來自 Channel9 目前於北美 TechEd 活動影片,主要記錄 DEV-B314 這一場 Microsoft ASP.NET, Web, and Cloud Tools Preview 的筆記。
以下將 Visual Studio 2013 Preview 相關內容整理如下:
Visual Studio 2013 Preview簡化一開始的新增專案的對話視窗,只區兩大類,進入後也只區分為Empty、Web Forms、MVC、Web API、SPA、Facebook、Mobile。
測試伺服器不在局限於IIS Express,也可以設置為外部伺服器。
當我們修改頁面文字、Layout、CSS等,可快速重整所有已連接至Visual Studio測試頁面的瀏覽器。
在新增專案時即可設置認證組態,目前可結合其他外部Microsoft Live Id、Facebook、Google+、twitter等。
Contains()
方法在很多地方都可以使用,主要是用來比較指定物件內是否含有指定的項目。例如:String 型別的 Contains()
方法就經常拿來搜尋或過濾字串使用。
Dim YesNo As Boolean = "Bruce很帥XD".Contains("帥") Console.WriteLine(If(YesNo, "帥", "不帥")) Console.ReadLine()
但今天想瞭解在含有大量資料時,集合與泛型集合內的Contains方法的處理速度。
想瞭解與測試的原因是因為亂馬客寫了一篇 .NET]產生不重覆的數值(List vs HashSet) 的文章,他測試結果是正確的,不過我認為測試範圍可以加大到集合與泛型集合,所以有了以下測試程式碼與測試結果。程式碼參考亂馬客文章進行修改,主要加入了 Counter 變數,記錄下 while
迴圈的執行次數,這樣比較能瞭解誤差值。
程式碼主要是要產生不重覆的數值,所以重點其實只在 while
那一行程式碼,這裡我加大數值的量,由 1 ~ 100000 裡取出不重覆的 90000 個數值。因為我們只單存取一個數值,所以 Key/Value 的集合與泛型集合就不在測試程式碼之內。
提供基礎類別來傳送 HTTP requests(請求)和接收 HTTP responses(回應)從一個 URI 的資源定義。目前 HttpClient 類別為 .NET Framework 4.5 Beta 中 System.Net.Http 命名空間之下,使用方式在未來正式版中可能會有修改,以下所提範例在未來是否能正常運作是未知,但提供的觀念我相信是一樣的。
HttpClient 類別執行個體做為發送的 HTTP 請求的會話(session),HttpClient 執行個體是應用於該執行個體來執行所有請求的設定的集合。此外,每一個 HttpClient 執行個體將使用自己的連接池(connection pool),以隔離來自其他 HttpClient 執行個體所執行的請求的請求。
我們先看一個最簡單的範例,我們開一個【主控台應用程式】:
圖一:比較 WCF 與 Web API from thedatafarm.com |
註:以下內容,會使用 Visual Studio 11 Beta 來實作,因 VS 11 還未有正體中文版,與 VS 11 相關步驟會使用英文。另外,可順便先熟悉 VS 11 開發環境。除簡化的圖示不談,整體開發功能是更上一層樓。
![]() |
圖二:選擇 ASP.NET MVC 4 專案 |
![]() |
圖三:選擇 Web API 樣版 |
之前,我在接觸 ASP.NET MVC 3 時,有點想去學 Razor 語法,因為大家一直強調 Razor 的好處,也讓我小小心動,不過,每一次接觸這種 v1 東西總是讓我碰壁,在 Visual Studio 2010 + Visual Basic 2010 + MVC 3 + Razor 環境裡,Visual Studio 2010 當的不像話,隨便打個 @html. 就可以當好幾次,後來還是把心思放在 MVC 上就好。但在 Visual Studio 11 裡中,VB中 Web API 只的支援 Razor,資料沒看錯的話,Visual Studio 11中 是 Razor v2。目前還沒有去 View 裡認真玩,簡單打一些 keyword 是沒有之前當掉情況,未來有 VB for Razor 的心得,再寫上來。
Module Module1 Private Sub GenerationDemo() ' 了解 GC 最大為 0, 1, 2 三層 Console.WriteLine("最大 GC 代: {0} ", GC.MaxGeneration) ' Heap 新增一物件 Dim obj As New GenObj("Generation") ' 顯示目前物件在 GC 第幾層 obj.DisplayGeneration() For i As Integer = 1 To GC.MaxGeneration ' 進行 GC 收集動作 GC.Collect() ' 因為 obj 沒被回收 ' 每次會被拉高一層代 obj.DisplayGeneration() Next obj = Nothing For i As Integer = 0 To GC.MaxGeneration ' 強制立即執行層代零至指定層代的記憶體回收。 GC.Collect(i) ' 暫止目前的執行緒,直到處理完成項佇列的執行緒已經清空該佇列為止。 GC.WaitForPendingFinalizers() Next Console.WriteLine("Demo Stop.") End Sub Sub Main() GenerationDemo() Console.ReadLine() End Sub End Module Class GenObj Private _name As String Sub New(name As String) name = _name End Sub ' 回傳目前物件所在 GC 第幾層 Sub DisplayGeneration() Console.WriteLine("我在第 {0} 層", GC.GetGeneration(Me)) End Sub End Class
我只是一個平凡人,如果我能,你也能。by KKBruce首先,我一定要感謝我最愛的家人們,不管什麼時候、什麼事,你們都永遠支持我。再來感謝所有幫助過我的人,因為有你們的表率,讓我有學習的對象,讓我有機會成為一位Microsoft MVP。
圖一:Microsoft MVP獎項 |
圖二:2012 Microsoft MVP獎盃 |
舊未讀,新又來。
舊的未讀,新的又來。
舊的未讀熟,新的又來亂。(by KKBruce)