DbTableToHtml Windows Workflow Activity

Статья описывает Windows Workflow Activity DbTableToHtml. Activity разработан на языке C#. Activity читает содержимого полей одной или нескольких таблиц базы данных, формирует на основе считанных данных DataSet, затем на основе DataSet формирует XML документ, затем на основе XML документа формирует HTML документ, который передается клиенту по технологии WCF.
Представлен рабочий проект MS Visual Studio 2010 WCF + WorkFlow, в котором применяется описываемое Activity. В состав проекта входят WorkFlow, библиотека входных и выходных классов, Windows Form клиент запрашивающий, получающий и отображающий данные с сервера при помощи компонента WebBrowser.
1. Входные данные Activity DbTableToHtml.
Входные аргументы для Activity собраны в классе InputArguments и состоят из трех полей:
public class InputArguments
{
    public string ConnectStrig  { get; set; }
    public string SqlCommand    { get; set; }
    public string XsltFileName  { get; set; }
}
2. Выходные данные Activity DbTableToHtml.
Выходные аргументы для Activity находяться в класса OutputResult и состоят из двух свойств: ResultHtmlDoc - выходной документ и Error - сообщения о потенциально возможной ошибке.
public class OutputResult
{
     public string ResultHtmlDoc  { get; set; }
     public string Error          { get; set; }
}
3. Исходный текст Activity DbTableToHtml.
Класс реализующий Activity DbTableToXml создан асинхронным, содержащим два метода:
  • BeginExecute;
  • EndExecute.
Как видно из приведенного ниже текста, SQL запрос запускается в методе BeginExecute, затем работа Activity приостаналивается и завершается процесс в методе EndExecute.
/*  21.09.2012. Рекомендуется для публикации.   
    1. Activity читает содержимое таблицы в базе данных Nortwind и переводит их в XML файл
    а затем в HTML файл.
    2. Входным параметром является класс InputArguments с полями:  
        public string ConnectStrig  { get; set; }
        public string SqlCommand    { get; set; }
        public string XsltFileName  { get; set; }
    3. Выходным аргументом является класс OutputResult с полями:
        public string ResultHtmlDoc { get; set; }
        public string Error         { get; set; }   
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Xml;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Windows.Markup;
using System.ComponentModel;
using System.Xml.Linq;
using System.Xml.Xsl;

using ClassLibrary;
using System.Diagnostics;

namespace ActivityLibrary
{
    public sealed class DbTableToHtml : AsyncCodeActivity<OutputResult>
    {  
        // Input Object
        [RequiredArgument]
        [DefaultValue(null)]
        public InArgument<InputArguments> inpArg { get; set; }

        // Temporary variable for input arguments
        private InputArguments inputObj     = null;
        private string connectStr           = null;
        private string cmdSQL               = null;
        private string xslFileName          = null;

        //Output Object
        private OutputResult OutRes = null;

        // Temporary use variable
        private DataSet dataSet             = null;
        private SqlConnection connect       = null;
        private SqlCommand command          = null;
        private SqlDataAdapter adapter      = null;
        private StringBuilder strBuilder    = null;
        private StringWriter strWriter      = null;
        private SqlDataReader reader        = null;
        private XslCompiledTransform xslt   = null;
        private XmlReader XmlRead           = null;


       protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        {         
            try
            {
                 // Input Object
                inputObj = inpArg.Get(context);
                // Connection string
                connectStr  = inputObj.ConnectStrig;
                // Command string
                cmdSQL      = inputObj.SqlCommand;
                // xslFileName
                xslFileName = inputObj.XsltFileName;

                // If connect string is empty
                if (String.IsNullOrEmpty(connectStr)) throw new ArgumentNullException("Value", "Connection String is Empty");

                // If command string is empty
                if (String.IsNullOrEmpty(cmdSQL)) throw new ArgumentNullException("Value", "Command String is Empty");

                // If xslFileName is empty
                if (String.IsNullOrEmpty(xslFileName)) throw new ArgumentNullException("Value", "xslFileName is Empty");

                connect = new SqlConnection(connectStr);
                connect.Open();
                command = new SqlCommand(cmdSQL, connect);
                adapter = new SqlDataAdapter(command);
                context.UserState = adapter;
                return adapter.SelectCommand.BeginExecuteReader(callback, state);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }

       protected override  OutputResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
       {
           SqlDataAdapter adapter = (SqlDataAdapter)context.UserState;
           OutRes   = new OutputResult();
           xslt     = new XslCompiledTransform();
           xslFileName = inputObj.XsltFileName;
           try
           {
               // End Execute Reader
               reader = adapter.SelectCommand.EndExecuteReader(result);
               reader.Close();
               // Create DataSet
               dataSet = new DataSet();
               adapter.Fill(dataSet);
               // Create XML document
               strBuilder = new StringBuilder();
               using (strWriter = new StringWriter(strBuilder)) { dataSet.WriteXml(strWriter); }
              
               // Create HTML document
               XmlRead = XmlReader.Create(new StringReader(strBuilder.ToString()));                 
               xslt.Load(xslFileName);     
               xslt.Transform(XmlRead, null, strWriter= new StringWriter());               
               OutRes.ResultHtmlDoc = strWriter.ToString();
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
               this.OutRes.Error = ex.ToString();
           }
           finally
           {
               this.connect.Close();
           }
           return OutRes;
       }
    }
}
4. Клиент для Activity DbTableToHtml.
Ниже приведен пример клиента, который организует запрос к серверу, принимает и отображает данные в двух компонентах, в TextBox и WebBrouser.
/* 21.09.2012
    Клиент для проверки Activity DbTableToXMLToHtml.
    1. Формирует и передает на сервер объест InputArguments.
    2. Принимает и отображает объест OutputResult.
    3. Отображение идет в двух окнах, в одном отображается код, в другом таблица с
      с данными компонентом WebBrowser.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ClassLibrary;
using System.Diagnostics;

namespace WindowsFormsClient
{
    public partial class Form1 : Form
    {
        ServiceReference.ServiceClient client;
        ClassLibrary.InputArguments input;
        ClassLibrary.OutputResult output;
        public Form1()
        {
            InitializeComponent();
            client = new ServiceReference.ServiceClient();
            input = new InputArguments();
            output = new OutputResult();
            textBox2.Text = @"Data Source=PROGR\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True; Asynchronous Processing=true";
            textBox3.Text = @"SELECT Orders.OrderID, Orders.CustomerID, Orders.ShipAddress FROM Orders";
            textBox4.Text = @"G:\Data\\uc1Избранное\DbToXmlToHtml\ClassLibrary\Transform.xslt";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                textBox1.Text = String.Empty;
                input.ConnectStrig = textBox2.Text;
                input.SqlCommand = textBox3.Text;
                input.XsltFileName = textBox4.Text;
                ClassLibrary.OutputResult output = new OutputResult();
                output = client.GetData(input);
                textBox1.Text = output.ResultHtmlDoc;
                webBrowser1.DocumentText = output.ResultHtmlDoc;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

Visual Studio 2010 проект содержащий: Activity, Workflow для Activity, Windows Form клиент можно загрузить.
Евгений Вересов.
21.09.2012 года.