首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WF 從入門到精通(第十三章):打造自定義活動(一)——核心架構與 FTP 下載實作

     編輯:關於.NET

章節目標

  • 掌握建立功能完整自定義工作流活動的必要組件
  • 從零建立基本自定義活動 FtpGetFileActivity
  • 理解活動生命週期、執行上下文與虛擬方法
  • 實作依賴屬性、Execute 方法與 FTP 核心邏輯

活動開發核心知識

活動基類常用虛擬方法

方法用途
Initialize活動初始化,分配資源
Execute核心執行邏輯,**最常重寫**
Cancel工作流取消時調用
HandleFault未處理例外時調用
Compensate事務補償(需實作 ICompensatableActivity)
Uninitialize反初始化,釋放資源
OnActivityExecutionContextLoad/Unload活動載入/卸載運行時

執行狀態與生命週期

活動執行上下文 (ActivityExecutionContext) 追蹤執行狀態。各虛擬方法僅允許返回特定狀態值(如 Execute 僅可回 Executing 或 Closed),否則拋出 InvalidOperationException。

生命週期順序:OnActivityExecutionContextLoad → Initialize → Execute → Uninitialize → OnActivityExecutionContextUnload → Dispose。注意活動通常由反序列化建立,故資源分配宜在 OnActivityExecutionContextLoad 而非建構子。

建立 FtpGetFileActivity 步驟實錄

1. 專案與引用準備

  • 方案加入類別庫專案 FtpActivity
  • 參考:System.Drawing、System.Windows.Forms、System.Workflow.Activities、System.Workflow.ComponentModel、System.Workflow.Runtime

2. 類別繼承與依賴屬性

public 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(驗證等級)。

3. 匿名登入常數

private const string AnonymousUser = "anonymous";
private const string AnonymousPassword = "someone@example.com";

4. Execute 方法與 GetFile 核心邏輯

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 確保資源釋放。

宿主應用程式 FileGrabber

WinForms 介面提供 FTP URL、帳號、密碼輸入,非同步啟動工作流避免 UI 凍結。下載檔案儲存於執行檔同目錄。完整代碼見配套原始碼。

下一步預告

下篇將加入:自定義驗證器(設計時檢查必塊欄位)、工具箱位圖、視覺化設計器主題、工具箱項目自定義名稱,打造專業級活動體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved