FtpGetFileActivity| 方法 | 用途 |
|---|---|
| Initialize | 活動初始化,分配資源 |
| Execute | 核心執行邏輯,**最常重寫** |
| Cancel | 工作流取消時調用 |
| HandleFault | 未處理例外時調用 |
| Compensate | 事務補償(需實作 ICompensatableActivity) |
| Uninitialize | 反初始化,釋放資源 |
| OnActivityExecutionContextLoad/Unload | 活動載入/卸載運行時 |
活動執行上下文 (ActivityExecutionContext) 追蹤執行狀態。各虛擬方法僅允許返回特定狀態值(如 Execute 僅可回 Executing 或 Closed),否則拋出 InvalidOperationException。
生命週期順序:OnActivityExecutionContextLoad → Initialize → Execute → Uninitialize → OnActivityExecutionContextUnload → Dispose。注意活動通常由反序列化建立,故資源分配宜在 OnActivityExecutionContextLoad 而非建構子。
FtpActivitySystem.Drawing、System.Windows.Forms、System.Workflow.Activities、System.Workflow.ComponentModel、System.Workflow.Runtimepublic sealed class FtpGetFileActivity : System.Workflow.ComponentModel.Activity {
// 依賴屬性註冊
public static DependencyProperty FtpUrlProperty = DependencyProperty.Register("FtpUrl", typeof(string), typeof(FtpGetFileActivity));
public static DependencyProperty FtpUserProperty = DependencyProperty.Register("FtpUser", typeof(string), typeof(FtpGetFileActivity));
public static DependencyProperty FtpPasswordProperty = DependencyProperty.Register("FtpPassword", typeof(string), typeof(FtpGetFileActivity));
// ... 屬性包裝器(含驗證邏輯)
}
屬性特性說明:Description(屬性面板提示)、DesignerSerializationVisibility.Visible(設計時序列化)、Browsable(true)(顯示編輯框)、Category(分組)、ValidationOption.Required/Optional(驗證等級)。
private const string AnonymousUser = "anonymous";
private const string AnonymousPassword = "someone@example.com";
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) {
GetFile();
return ActivityExecutionStatus.Closed;
}
private void GetFile() {
Uri requestUri = new Uri(FtpUrl); // 重驗證,因繫結可能繞過 setter
if (requestUri.Scheme != Uri.UriSchemeFtp) throw new ArgumentException("無效 FTP URI");
string fileName = Path.GetFileName(requestUri.AbsolutePath);
if (String.IsNullOrEmpty(fileName)) return;
Stream bitStream = null, fileStream = null;
try {
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(requestUri);
// 認證憑證
if (!String.IsNullOrEmpty(FtpUser))
request.Credentials = new NetworkCredential(FtpUser, FtpPassword);
else
request.Credentials = new NetworkCredential(AnonymousUser, String.IsNullOrEmpty(FtpPassword) ? AnonymousPassword : FtpPassword);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
bitStream = response.GetResponseStream();
fileStream = File.Create(fileName);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bitStream.Read(buffer, 0, buffer.Length)) > 0)
fileStream.Write(buffer, 0, bytesRead);
} finally {
if (bitStream != null) bitStream.Close();
if (fileStream != null) fileStream.Close();
}
}
關鍵點:繫結會直接寫入依賴屬性略過 setter,故 Execute 中需重驗證 URI;使用 FtpWebRequest/Response 實現下載;finally 確保資源釋放。
WinForms 介面提供 FTP URL、帳號、密碼輸入,非同步啟動工作流避免 UI 凍結。下載檔案儲存於執行檔同目錄。完整代碼見配套原始碼。
下篇將加入:自定義驗證器(設計時檢查必塊欄位)、工具箱位圖、視覺化設計器主題、工具箱項目自定義名稱,打造專業級活動體驗。