# Alex FTPS 因為原生.net 的FTP lib 不支援Implicit模式的FTPS 所以一定要用第三方來做 1. FluentFTPS 2. Alex FTPS 只有這兩個是自由軟體 Alex很久沒維護了(2015), FluentFTPS Implicit有錯誤的問題,也沒解決 所以選Alex,Alex的說明資源不多,大致研究如下 ESSLSupportMode是選Implicit ```csharp= using (FTPSClient client = new FTPSClient()) { NetworkCredential networkCredential = new NetworkCredential() { UserName = "user", Password = "pass" }; client.Connect("123.234.345.456", networkCredential, ESSLSupportMode.Implicit, new RemoteCertificateValidationCallback(ValidateTestServerCertificate)); ``` 前面Credential都好懂,但**RemoteCertificateValidationCallback** 要另外處理,加上 ```csharp= private static bool ValidateTestServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } ``` 用來接收所有Certification證書,很多FTPS 的X509證書都是自簽的,變成說要Pass過這個證書檢查才能用 ```csharp= client.SetCurrentDirectory("dictionary"); client.StartKeepAlive(); ``` 不多說,好懂 再來是PutFile ```csharp= client.PutFile("localfilepath", "remotefilepath", new FileTransferCallback(TransferCallbackFunction)); ``` 最主要說明這個**FileTransferCallback** 他是Delegate Function, 代表它把方法當成參數傳送,也就是 Server的 FileTransferCallback 回傳值,一定要用一個Function來接,因此就寫一個一樣的Function ```csharp= private static void TransferCallbackFunction(FTPSClient sender, ETransferActions action, string localObjectName, string remoteObjectName, ulong fileTransmittedBytes, ulong? fileTransferSize, ref bool cancel) { switch (action) { case ETransferActions.FileUploaded: OnFileTransferCompleted(fileTransmittedBytes, fileTransferSize, localObjectName); break; } } ``` 收到傳回來得資料,可以在Argument欄位看到會有甚麼資料回來, 主要Action比較重要,他定義了一些傳輸動作,像是 1. 上傳完成 2. 上傳狀態 3. 下載狀態 4. 下載完成 5. 目錄建立 6. 目錄移除 等等 我們只要對這些Action做處理就好了,所以再加上 ```csharp= private static void OnFileTransferCompleted(ulong fileTransmittedBytes, ulong? fileTransferSize, string localObjectName) { if (fileTransferSize != null) { if (fileTransferSize != fileTransmittedBytes) { TransferResult = $"WARNING: transfer file {localObjectName} size ({fileTransferSize.Value}) differs from the transferred bytes count ({fileTransmittedBytes}) At {string.Format("{0:yyyyMMddHHmmss}", DateTime.Now)} "; return; } } TransferResult = "Success"; } ``` TransferResult 這個是全域的String,拿來當作狀態紀錄 比較好在其他Function內做使用 參考資料: [Alex FTPSv2](https://github.com/luck02/FTPSClient/tree/f2a9cef0daa82f70747df52a41a918a4712f88b8) [Delegate Function](https://eric0806.blogspot.com/2015/01/dotnet-delegate-usage.html) ###### tags: `C#`,`FTPS`,`FTP`