本文快速詳細介紹了您需要執行的步驟,以便在ASP.NET(經典或MVC)中支持Windows Workflow Foundation(WF)。讓我們使用一個非常小的演示應用程序向您展示如何執行此操作。
將WF集成在ASP.NET中是我在工作的最後幾個項目中必須做的事情。因此,我認為我會構建一個少量的示例應用程序,向您顯示實現此目的所需的最少代碼。讓我們逐步構建示例申請...
備註:本文不是WF的入門。需要對WF的一些基本理解。
啟動SQL Server Management Studio並創建一個名為“ Workflow”的新數據庫。您需要創建一些表和邏輯(存儲過程等),以支持WF的持久性。在目錄中“ C: Windows Microsoft.net Framework V3.0 Windows Worksflow Foundation sql en”您會找到4個SQL文件。按以下順序執行以下兩個:
這創建了兩個表和10個存儲過程,以支持SQL Server數據庫中的WF持續性。現在,下載本文的源代碼,提取並執行DDL.SQL腳本。該腳本創建一個稱為客戶的表。
您應該結束一個看起來像這樣的數據庫結構:
圖1-工作流數據庫

當您打開本文的示例解決方案時,您會找到一個名為“數據庫”的代碼庫項目。它包含的只是一個Linq到SQL類文件,其中包含一個實體,即客戶。
圖2-客戶實體

示例應用程序允許您創建客戶。您要做的就是輸入用戶名。之後,開始了一個新的工作流程,您可以選擇批准客戶,拒絕他或什麼都不做。如果您不採取行動,則在一定超時後,客戶將被刪除。
圖3-工作流程

在此示例中,有一個狀態機工作流程。對於這樣的工作流,您必須提供初始和完整的狀態。如上圖所示,它僅包含兩個適當命名的狀態。
此工作流需要一個稱為用戶名的參數。當它到達初始狀態時,執行了狀態化攻擊性,並在客戶表中創建並堅持使用新客戶。默認情況下,所有客戶都需要批准。
圖4-等待批准的客戶

我將這個工作流程放在一個單獨的項目中。
圖5-解決方案

當狀態化攻擊完成後,執行工作流將聆聽3個可能的事件之一:
超時事件依賴於延遲性。您不必自己解僱此事件,但是您負責解僱其他兩個事件。因此,我創建了本地服務。
清單1- icustomerService接口
[ ExternalDataExchange ]
public interface ICustomerService
{
event EventHandler < ExternalDataEventArgs > Approved ;
event EventHandler < ExternalDataEventArgs > Rejected ;
}您只能在工作流運行時註冊一個本地服務的實現,而客戶服務的實現如下:
清單2-客戶服務
public class CustomerService : ICustomerService
{
public event EventHandler < ExternalDataEventArgs > Approved ;
public event EventHandler < ExternalDataEventArgs > Rejected ;
private bool FireEvent ( EventHandler < ExternalDataEventArgs > theEvent , ExternalDataEventArgs args )
{ //...}
public bool OnApproved ( Guid instanceId )
{
return FireEvent ( Approved , new ExternalDataEventArgs ( instanceId ) ) ;
}
public bool OnRejected ( Guid instanceId )
{
return FireEvent ( Rejected , new ExternalDataEventArgs ( instanceId ) ) ;
}
}此本地服務使您可以通過指定要繼續執行的工作流的實例ID(GUID)來觸發批准的或拒絕的事件。
創建,批准或拒絕客戶的邏輯不多,但是我將所有內容都放在CustomManager類中。這些方法是不言自明的。此課程使您可以檢索所有客戶的列表,添加新客戶,批准,拒絕和刪除客戶。
列表3-定制員類
public class CustomerManager
{
public IEnumerable < Customer > GetCustomers ( ) { //... }
public Customer GetCustomerById ( Guid customerId ) { //... }
public void ApproveCustomer ( Guid customerId ) { //... }
public void RejectCustomer ( Guid customerId ) { //... }
public void DeleteCustomer ( Guid customerId ) { //... }
public void AddCustomer ( Guid customerId , string userName ) { //... }
}該工作流使用此定制類型類型來執行其所有工作。
瞧,基礎是奠定的。您已經設置了一個支持WF持久性的數據庫,創建了用於創建,批准和拒絕客戶的工作流程,並創建了一項本地服務,該服務將幫助您指導工作流程實例。
現在,讓我們創建一個新的ASP.NET Web應用程序,該應用程序將使所有這些都起作用。我為ASP.NET項目提出了原始名稱“ WebApplication”。
圖6-網絡應用項目

該站點僅包含一個稱為default.aspx的頁面。此頁面顯示客戶列表,允許您添加新客戶並批准或拒絕現有客戶。
圖7 -default.aspx頁面

讓我們配置Web應用程序,以便它支持WF。本文中顯示的配置代碼縮寫為可讀性。下載完整版本的示例源代碼。
打開您的應用程序配置文件(web.config),然後將以下行添加到“配置”部分。
< configSections >
<!-- ... -->
< section name = " WorkflowRuntime "
type = " System.Workflow.Runtime.Configuration.WorkflowRuntimeSection...etc. " />
</ configSections >您需要將此行添加到配置節點中,以便.NET知道它必須使用WorkFlowRuntimeSection類型來讀取以下配置,您需要將其添加到配置節點。
< WorkflowRuntime >
< CommonParameters >
< add name = " ConnectionString " value = " your connection string " />
</ CommonParameters >
< Services >
< add type = " System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService,...etc. "
useActiveTimers = " true " />
< add type = " System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,...etc. "
UnloadOnIdle = " true " LoadIntervalSeconds = " 5 " />
</ Services >
</ WorkflowRuntime >WorkFlowRuntime節點為工作流運行時加載ManualWorkFlowsChedulerService和SQLWorkFlowPersisservice服務。如果要持續工作流程,並且對於ASP.NET,建議使用ManualworkFlowsChedulerService而不是DefaultWorkWorkflowsChedulerService Service,則必須加載SQLWorkFlowPersistService。
每個工作流實例在單獨的線程上執行。 Workflow運行時使用Workflow Scheduler服務管理此操作。默認情況下,運行時使用DefaultWorkflowsChedulerService類型。所有工作流程實例都以異步方式執行。
對於ASP.NET,最好使用ManualWorkflowsChedulerService,因為它允許您同步運行工作流程。在這種情況下,工作流運行時使用了從主機應用程序中的調用線程。
這使您可以在ASP.NET發送響應之前等待工作流的響應。當然,在這種情況下,執行工作流程中的任何長期運行任務是不明智的。 (PS:查看此博客文章以獲取有關此主題的更多信息。)
使用ManualWorkflowsChedulerService時,請確保將UseActiveTimers屬性設置為true。如果將此設置設置為false的默認值,則任何延遲活動都不會在過期後自動恢復。如果設置為true,則工作流運行時將使用內存計時器定期檢查過期的延遲活動。
現在,您的應用程序已配置為使用WorkFlow Foundation,您需要託管工作流運行時。
在ASP.NET中,這樣做的理想場所是在global.asax文件中。只需將以下代碼添加到application_start(...)事件處理程序。
列表4- global.asax application_start
protected void Application_Start ( object sender , EventArgs e )
{
WorkflowRuntime runtime = new WorkflowRuntime ( "WorkflowRuntime" ) ;
ExternalDataExchangeService exchangeService = new ExternalDataExchangeService ( ) ;
runtime . AddService ( exchangeService ) ;
CustomerService customerService = new CustomerService ( ) ;
exchangeService . AddService ( customerService ) ;
runtime . StartRuntime ( ) ;
Application [ "WorkflowRuntime" ] = runtime ;
}創建了WorkFlowRuntime的新實例,然後創建並將其添加到運行時。接下來,我們創建一個本地服務IcustomerService的實例,然後將其添加到外部Dataexchangeservice實例中。最後,運行時開始並存儲在應用程序的狀態中。
同樣,當應用程序結束時,您需要停止工作流運行時,如列表5所示。
列表5 -global.asax Application_end
protected void Application_End ( object sender , EventArgs e )
{
WorkflowRuntime runtime = Application [ "WorkflowRuntime" ] as WorkflowRuntime ;
if ( runtime != null )
{
runtime . StopRuntime ( ) ;
runtime . Dispose ( ) ;
}
} 單擊“添加”按鈕時,您需要啟動新的工作流程。當使用ManualWorkflowsChedulerService時,您將完全控制運行工作流程實例。在清單6中,您可以看到您需要遵循以下步驟:
清單6-創建一個新客戶
WorkflowRuntime runtime = ( WorkflowRuntime ) Application [ "WorkflowRuntime" ] ;
Dictionary < string , object > arguments = new Dictionary < string , object > ( ) ;
arguments . Add ( "UserName" , txtUserName . Text . Trim ( ) ) ;
WorkflowInstance workflow = runtime . CreateWorkflow ( typeof ( CustomerApprovalWorkflow ) , arguments ) ;
workflow . Start ( ) ;
ManualWorkflowSchedulerService scheduler =
( ManualWorkflowSchedulerService ) runtime . GetService ( typeof ( ManualWorkflowSchedulerService ) ) ;
scheduler . RunWorkflow ( workflow . InstanceId ) ; 創建客戶後,您可以批准或拒絕他的帳戶。換句話說,您需要繼續創建他的帳戶時開始的工作流程。
清單7中顯示的代碼類似於清單6的代碼。唯一的區別是您必須檢索本地服務的實例(CustomerService),並稱其為徵用(...)方法。掌握的方法觸發了批准的事件。成功交付後,您可以指示調度程序繼續運行工作流程。
清單7-批准客戶
WorkflowRuntime runtime = ( WorkflowRuntime ) Application [ "WorkflowRuntime" ] ;
ManualWorkflowSchedulerService scheduler =
( ManualWorkflowSchedulerService ) runtime . GetService ( typeof ( ManualWorkflowSchedulerService ) ) ;
CustomerService customerService = ( CustomerService ) runtime . GetService < ICustomerService > ( ) ;
if ( customerService . OnApproved ( customerId ) )
{
scheduler . RunWorkflow ( customerId ) ;
}拒絕客戶的帳戶相似。您只需要發送被拒絕的事件而不是批准的事件。如果您不採取行動,則將在一分鐘後觸發延遲率,並且客戶的帳戶將自動刪除。
這就是其中的全部。