WF从入门到精通(第十三章):打造自定义活动(二)2010-06-03 cnblogs GuoYong.CheFtpGetFileActivity类using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.ComponentModel; using System.ComponentModel.Design; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Design; using System.Workflow.Activities; using System.Drawing; namespace FtpActivity { [Designer(typeof(FtpGetFileActivityDesigner), typeof(IDesigner))] [ToolboxBitmap(typeof(FtpGetFileActivity), "FtpImage.bmp")] [ToolboxItem(typeof(FtpGetFileActivityToolboxItem))] [ActivityValidator(typeof(FtpGetFileActivityValidator))] public sealed class FtpGetFileActivity : System.Workflow.ComponentModel.Activity { public static DependencyProperty FtpUrlProperty = DependencyProperty.Register("FtpUrl", typeof(System.String), typeof(FtpGetFileActivity)); [Description("Please provide the full URL for the file to download.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [ValidationOption(ValidationOption.Required)] [Browsable(true)] [Category("FTP Parameters")] public string FtpUrl { get { return ((string)(base.GetValue(FtpGetFileActivity.FtpUrlProperty))); } set { Uri tempUri = null; if (Uri.TryCreate(value, UriKind.Absolute, out tempUri)) { if (tempUri.Scheme == Uri.UriSchemeFtp) { base.SetValue(FtpGetFileActivity.FtpUrlProperty, tempUri.AbsoluteUri); } } else { // Not a valid FTP URI throw new ArgumentException("The value assigned to the FtpUrl property is not a valid FTP URI."); } } } public static DependencyProperty FtpUserProperty = DependencyProperty.Register("FtpUser", typeof(System.String), typeof(FtpGetFileActivity)); [Description("Please provide the FTP user account name.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [ValidationOption(ValidationOption.Optional)] [Browsable(true)] [Category("FTP Parameters")] public string FtpUser { get { return ((string)(base.GetValue(FtpGetFileActivity.FtpUserProperty))); } set { base.SetValue(FtpGetFileActivity.FtpUserProperty, value); } } public static DependencyProperty FtpPasswordProperty = DependencyProperty.Register("FtpPassword", typeof(System.String), typeof(FtpGetFileActivity)); [Description("Please provide the FTP user account password.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [ValidationOption(ValidationOption.Optional)] [Browsable(true)] [Category("FTP Parameters")] public string FtpPassword { get { return ((string)(base.GetValue(FtpGetFileActivity.FtpPasswordProperty))); } set { base.SetValue(FtpGetFileActivity.FtpPasswordProperty, value); } } private const string AnonymousUser = "anonymous"; private const string AnonymousPassword = "someone@example.com"; protected override ActivityExecutionStatus Execute( ActivityExecutionContext executionContext) { // Retrieve the file. GetFile(); // Work complete, so close. return ActivityExecutionStatus.Closed; } private void GetFile() { // Create the Uri. We check the validity again // even though we checked it in the property // setter since binding may have taken place. // Binding shoots the new value directly to the // dependency property, skipping our local // getter/setter logic. Note that if the URL // is very malformed, the Uri constructor will // throw. Uri requestUri = new Uri(FtpUrl); if (requestUri.Scheme != Uri.UriSchemeFtp) { // Not a valid FTP URI throw new ArgumentException("The value assigned to the FtpUrl property is not a valid FTP URI."); } // if string fileName = Path.GetFileName(requestUri.AbsolutePath); if (String.IsNullOrEmpty(fileName)) { // No file to retrieve. return; } // if Stream bitStream = null; FileStream fileStream = null; StreamReader reader = null; try { // Open the connection FtpWebRequest request = (FtpWebRequest)WebRequest.Create(requestUri); // Establish the authentication credentials if (!String.IsNullOrEmpty(FtpUser)) { request.Credentials = new NetworkCredential(FtpUser, FtpPassword); } // if else { request.Credentials = new NetworkCredential(AnonymousUser, !String.IsNullOrEmpty(FtpPassword) ? FtpPassword : AnonymousPassword); } // else // Make the request and retrieve response stream FtpWebResponse response = (FtpWebResponse)request.GetResponse(); bitStream = response.GetResponseStream(); // Create the local file fileStream = File.Create(fileName); // Read the stream, dumping bits into local file byte[] buffer = new byte[1024]; Int32 bytesRead = 0; while ((bytesRead = bitStream.Read(buffer, 0, buffer.Length)) > 0) { fileStream.Write(buffer, 0, bytesRead); } // while } // try finally { // Close the response stream if (reader != null) reader.Close(); else if (bitStream != null) bitStream.Close(); // Close the file if (fileStream != null) fileStream.Close(); } // finally } } }其中接下来要做的一个更重要的事情是创建一个自定义验证器。尽管你可以使用该FTP活动了,因为它现在已经存在,但此时它是不完整的引入到工作流视图设计器中的。它所缺少的是属性验证。我们就来看看怎样添加一个验证器。