WF从入门到精通(第十三章):打造自定义活动(二)

FtpGetFileActivity类

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活动了,因为它现在已经存在,但此时它是不完整的引入到工作流视图设计器中的。它所缺少的是属性验证。我们就来看看怎样添加一个验证器。

时间: 2024-10-02 02:40:35

WF从入门到精通(第十三章):打造自定义活动(二)的相关文章

WF从入门到精通(第二章):workflow运行时

学习完本章后,你将掌握: 1.在你的应用程序中使用workflow 2.理解"WorkflowRuntime"对象的的基本功能 3.知道如何启动和停止workflow运行时 4.能够使用各种workflow运行时的相关事件 当你在WF环境中执行任务时,需要一些东西来监管执行的过程,这个东西就是命名为"WorkflowRuntime"的对象.WorkflowRuntime启动一个独立的工作流任务.在你的任务执行过程中,WorkflowRuntime也会针对不同的情况响

WF从入门到精通(第一章):WF简介

学习完本章,你将掌握: 1.了解工作流的概念和理论 2.把WF和BizTalk与WCF做比较 3.开始使用WF进行编程 4.知道怎样使用Visual Studio工作流支持.以下是一小段进行邮政编码验证的代码 string USCode = @"^(\d{5}$)|(\d{5}$\-\d{4}$)"; string CanadianCode = @"[ABCEGHJKLMNPRSTVXY]\D[A-Z]\d[A-Z]\d"; public static bool V

WF从入门到精通(第九章):逻辑流活动

学习完本章,你将掌握: 1.学会怎样使用IfElse活动来执行条件表达式 2.学会怎样使用While活动来执行循环 3.理解Replicator活动是怎样来模拟for循环的,以及它的使用方法. 我们已经看到过怎样执行工作流内部和外部的代码,已经知道怎样处理异常,暂停进程,在事情脱离控制时终止我们的工作流.但无疑对于任何一个计算机系统的主要组成部分来说,都应具有根据运行时的条件做出判断以执行不同的任务的能力.在本章,我们将演示要求我们应付if/else场景及基本的循环的一些工作流活动. 条件及条件

WF从入门到精通

WF从入门到精通(第十九章):把工作流发布为Web服务 WF从入门到精通(第十八章):在你的工作流中调用Web服务 WF从入门到精通(第十七章):关联及本地主机通信(下) WF从入门到精通(第十七章):关联及本地主机通信(上) WF从入门到精通(第十六章):声明式工作流 WF从入门到精通(第十五章):工作流和事务 WF从入门到精通(第十四章):基于状态的工作流 WF从入门到精通(第十二章):策略和规则 WF从入门到精通(第十三章):打造自定义活动(二) WF从入门到精通(第十三章):打造自定义活

WF从入门到精通(第四章):活动及workflow类型介绍

学习完本章,你将掌握: 1.workflow活动是怎样形成的 2.顺序工作流和状态机工作流之间的区别 3.创建一个顺序工作流 4.创建一个状态机工作流 活动是WF中workflow处理的基本单位,假如你再把一个业务处理过程(或workflow任务)进行分解,你会发现它由更小.更细的任务组成.假如需设计这样一个大的任务,它需把信息送到一系列的数据处理系统进行处理,那么子任务或许就包括这样一些事情:从数据库读取数据,使用这些数据生成一个文件,通过使用FTP或XML Web service把文件传到一

WF从入门到精通(第十三章):打造自定义活动(一)

学习完本章,你将掌握: 1.了解对于创建一个功能齐全的自定义工作流活动来说哪些组件是必须的 2.创建基本的自定义工作流活动 3.在基本的自定义工作流活动中应用验证规则 4.把基本的自定义工作流活动集成到Microsoft Visual Studio的工作流视图设计器和工具箱中 WF并不可能涵盖到你可能在你的工作流中想要实现的各个方方面面.即使WF对于开发社区来说仍是非常新的技术,但目前已经可以获得许多免费发布的自定义活动,可以肯定商业级的活动最终也会跟进. 在这章中,你将通过创建一个新的工作流活

WF从入门到精通(第十七章):关联及本地主机通信(上)

学习完本章,你将掌握: 1.了解工作流关联(correlation)以及在什么地方必须去使用它.它为什么是重要的 2.使用工作流关联参数(correlation parameters) 3.生成并使用相关的本地通信服务 贯穿本书你看过的应用程序普遍都是基于单一相同架构的,通过WF的支持在工作流实例中执行任务.这些都是在应用程序和它的工作流实例间进行一对一的通信.假如你和一个工作流实例进行通信,你这样做保证了无论以任何方式在应用程序和工作流之间传送数据都不会被混淆.一个应用程序对应一个工作流. 但

WF从入门到精通(第十二章):策略和规则

1.知道在工作流处理过程中怎样进行策略和规则的处理 2.理解前向链接以及这是如何影响到基于规则的工作流处理过程的 3.为工作流处理过程创建规则 4.结合Policy活动来使用规则 我敢肯定,我们中的大多数人编写面向过程的代码(imperative code)都很轻松自在.过程式代码指通过编程来实现业务处理过程的C#代码,例如,读取一个数据库表,增加这个表中某些列的值,然后把它们统统都写到另一个数据库的表中. 但在本章,我们将深入规则,规则是对工作流的执行进行控制的一种机制,但它被看作是声明性的(

WF从入门到精通(第七章):基本活动的操作

学习完本章,你将掌握: 1.知道怎样使用Sequence活动 2.知道怎样使用Code活动 3.知道在工作流中怎样抛出异常并对其进行处理 4.知道如何在代码中暂停和终止你的工作流实例 在本章,我们将正式引入前面已经看到过的一组活动:Sequence活动和Code活动.但我相信,适当的错误处理对于精心设计和运行良好的软件是至关重要的,所以我们将会研究如何使用工作流中的活动抛出异常.捕获异常.甚至暂停和终止你的工作流.我们就从Sequence活动开始吧. 使用顺序活动对象 实际上,说我们已见过Seq