Compartir a través de


Apéndice A: Desarrollo de la aplicación de pedidos

Este apéndice proporciona instrucciones detalladas para que los desarrolladores generen el servicio de pedidos de Contoso. El objetivo de este apéndice consiste en familiarizar a los desarrolladores con las aplicaciones de desarrollo que incluyen servicios Windows Communication Foundation (WCF) y/o Windows Workflow Foundation (WF) mediante Visual Studio 1010 y .NET Framework 4. La parte principal del tutorial usa esta aplicación para mostrar a los administradores del sistema o propietarios de aplicaciones cómo usar Windows Server AppFabric para implementar, realizar el seguimiento y solucionar problemas de las aplicaciones que incluyen servicios WCF y/o WF.

El servicio de pedidos de Contoso consta de las cuatro aplicaciones siguientes:

  • Servicio de procesamiento de pedidos: servicio WCF que simula una llamada a una aplicación de procesamiento de pedidos existente a través de interfaces de servicio web.

  • Servicio de envío: servicio WCF que simula una llamada a una aplicación de envío existente a través de API.

  • Servicio de flujo de trabajo de pedidos: servicio de flujo de trabajo WF que administra el proceso del pedido, incluidos su recepción, procesamiento y envío.

  • Cliente de pedidos: aplicación de Windows Form que actúa como front-end para el servicio de pedidos.

Nota

El apéndice no requiere la instalación de Windows Server AppFabric. Sin embargo, es necesario instalar los archivos del Tutorial sobre el uso de la interfaz de Windows Server AppFabric para crear una estructura de archivos que permita que el apéndice se genere correctamente. No es necesario seguir y completar el Tutorial sobre el uso de la interfaz de Windows Server AppFabric. Solo debe instalar los archivos. Para el procedimiento de instalación del Tutorial sobre el uso de la interfaz de Windows Server AppFabric, vea la Lección 1: Introducción. La carpeta C:\DublinTutorial\OrderServiceSolution\Completed contiene una copia de la solución completa.

Procedimiento

Para crear la aplicación, siga los pasos que se describen a continuación:

  1. Desarrollo del servicio WCF de procesamiento de pedidos

  2. Desarrollo del servicio WCF de envío

  3. Desarrollo del servicio WF de flujo de trabajo de pedidos

  4. Finalización del servicio WCF de procesamiento de pedidos

  5. Finalización del servicio WCF de envío

  6. Desarrollo de la aplicación cliente de pedido

  7. Empaquetado del servicio de pedidos

Desarrollo del servicio WCF de procesamiento de pedidos

La aplicación de procesamiento de pedidos es una aplicación que adquirió Contoso. Incluye servicios web con los que pueden comunicarse otras aplicaciones. Como desarrollador de Contoso, debe desarrollar un servicio WCF denominado OrderProcessingService para que interactúe con la aplicación de procesamiento de pedidos.

Procedimiento para crear una solución de Visual Studio y una aplicación de servicio WCF para OrderProcessingService

  1. Haga clic en Inicio, seleccione Todos los programas y Microsoft Visual Studio 2010 y, a continuación, haga clic en Microsoft Visual Studio 2010.

  2. Desde el menú Archivo, haga clic en Nuevo y, a continuación, en Nuevo proyecto.

  3. En Nuevo proyecto, seleccione o especifique los valores siguientes y haga clic en Aceptar.

    Propiedad Valor

    Tipos de proyecto

    Visual C#/Web

    Plantillas

    Aplicación del servicio de WCF

    Nombre

    OrderProcessingService

    Ubicación

    C:\DublinTutorial\OrderServiceSolution

    Nombre de la solución

    OrderService

    Crear directorio para la solución

    (seleccionado)

  4. En el Explorador de soluciones, amplíe OrderProcessingService, haga clic con el botón secundario del mouse en IService1.cs y, a continuación, seleccione Eliminar.

  5. Haga clic en Aceptar para confirmar que desea eliminar el archivo de forma permanente.

  6. En el Explorador de soluciones, amplíe OrderProcessingService, haga clic con el botón secundario del mouse en Service1.cs y, a continuación, seleccione Eliminar.

  7. Haga clic en Aceptar para confirmar que desea eliminar el archivo de forma permanente.

Para crear un servicio WCF, la primera tarea consiste en definir un contrato. El contrato especifica las operaciones que admite el servicio. Una operación puede considerarse un método de servicio web. Cada método de la interfaz se corresponde con una operación de servicio específica. En OrderProcessingService, se definen dos métodos: ProcessOrder y CancelOrderProcess.

Procedimiento para definir el contrato de servicio y el contrato de datos para el servicio de procesamiento de pedidos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderProcessService, seleccione Agregar y, a continuación, Nuevo elemento.

  2. En Agregar nuevo elemento - OrderProcessService, seleccione o especifique los valores siguientes y haga clic en Agregar.

    Propiedad Valor

    Categorías

    Visual C#/Web

    Plantilla

    Servicio WCF

    Nombre

    OrderProcessing.svc

    Se agregan dos archivos a la solución: IOrderProcessing.cs y OrderProcessing.svc.

  3. En el Explorador de soluciones, haga doble clic en el archivo IOrderProcessing.cs para abrirlo.

  4. Haga clic con el botón secundario del mouse en el espacio de nombres OrderProcessingService, haga clic en Refactorizar y, a continuación, en Cambiar nombre para abrir el cuadro de diálogo Cambiar nombre.

  5. En Nombre nuevo, escriba Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService y haga clic en Aceptar.

  6. Haga clic en Aplicar y, a continuación, en .

  7. Modifique el código fuente de OrderProcessing.svc para que tenga este aspecto:

    using System; 
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService
    {
        [ServiceContract]
        public interface IOrderProcessing
        {
            [OperationContract]
            string ProcessOrder(PurchaseOrder po);
    
            [OperationContract]
            string CancelOrderProcess(string orderID);
        }
    
        [DataContract]
        public class PurchaseOrder
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string FirstName;
            [DataMember]
            public string LastName;
            [DataMember]
            public string EmailAddress;
            [DataMember]
            public string TelephoneNumber;
            [DataMember]
            public string AddressLine1;
            [DataMember]
            public string AddressLine2;
            [DataMember]
            public string City;
            [DataMember]
            public string State;
            [DataMember]
            public string ZipCode;
            [DataMember]
            public string Description;
            [DataMember]
            public int Quantity;
            [DataMember]
            public string UnitPrice;
        }
    }
    

    En este archivo, se definen los contratos de datos y los contratos de servicio. Los clientes pueden llamar al servicio para procesar un pedido y para cancelar el procesamiento de pedidos.

Después de crear los contratos, que se definen mediante una interfaz, el paso siguiente consiste en implementar la interfaz. Esto implica la creación de una clase denominada OrderProcessService que implementa la interfaz definida por el usuario IOrderProcessing.

Procedimiento para implementar el contrato de servicio de procesamiento de pedidos

  1. En el Explorador de soluciones, haga doble clic en el archivo IOrderProcessing.cs para abrirlo.

  2. Modifique el código fuente para que tenga este aspecto:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    using System.IO;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService
    {
        class WorkItem
        {
            private Thread workThread;
            private object workItemLock;
            private bool completeFlag;
    
            public Thread WorkThread { get { return workThread; } set { workThread = value; } }
            public object WorkItemLock { get { return workItemLock; } }
            public bool CompleteFlag { get { return completeFlag; } }
    
            public WorkItem(Thread WorkThread)
            {
                workThread = WorkThread;
                workItemLock = new object();
                completeFlag = false;
            }
    
            public void Complete()
            {
                completeFlag = true;
            }
        }
    
        public class OrderProcessing : IOrderProcessing
        {
            private static Dictionary<String, WorkItem> WorkItemMap = new Dictionary<String, WorkItem>();
    
            public string ProcessOrder(PurchaseOrder po)
            {
                //run the code from a different thread to simulate asynchronized call
                ThreadPool.QueueUserWorkItem(SendProcessResult, po);
                return ("The request for processing order[" + po.POID + "] has been received.");
            }
    
            private void SendProcessResult(object state)
            {
                PurchaseOrder po = (PurchaseOrder)state;
    
                WorkItem workItem = new WorkItem(Thread.CurrentThread);
                WorkItemMap.Add(po.POID, workItem);
    
                //Simulating the order processing process
                Thread.Sleep(120000);
    
                //The following code will be uncommented later in the process
                //OrderWorkflowService.ProcessServiceResult reply = new OrderWorkflowService.ProcessServiceResult();
                //reply.POID = po.POID;
                //reply.Message = "The order has been processed successfully.";
    
                //lock (workItem.WorkItemLock)
                //{
                //    using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
                //    {
                //        client.SubmitProcessResult(reply);
                //    }
    
                //    workItem.Complete();
                //    WorkItemMap.Remove(po.POID);
                //}
    
            }
    
            public string CancelOrderProcess(string poID)
            {
                string ret = "Cancel unavailable for this order.";
    
                //=====================================================//
                //===[ Attempt to get a work item for the order Id 
                //=====================================================//
                WorkItem workItem;
                if (WorkItemMap.TryGetValue(poID, out workItem) == true)
                {
                    //===========================================================
                    //=== Slight race condition here. Workitem could complete
                    //=== before we aquire its lock. So we check the          
                    //=== completion flag inside the lock.                    
                    //===========================================================
                    lock (workItem.WorkItemLock)
                    {
                        if ((!workItem.CompleteFlag) && (workItem.WorkThread.IsAlive))
                        {
                            workItem.WorkThread.Abort();
                            WorkItemMap.Remove(poID);
                            ret = "The order process has been terminated successfully.";
                        }
                    }
                }
                return ret;
            }
        }
    }
    

El uso de un archivo de configuración ofrece la flexibilidad de proporcionar datos de comportamiento de servicio y extremo en el punto de desarrollo, en lugar de durante el diseño. En este archivo de configuración, se definen dos extremos.

Procedimiento para configurar el servicio de procesamiento de pedidos mediante un archivo de configuración

  1. En el Explorador de soluciones, amplíe OrderProcessingService y, a continuación, haga doble clic en el archivo Web.config para abrirlo. Agregue una etiqueta <services> dentro de la etiqueta <system.serviceModel>:

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.OrderProcessing">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.IOrderProcessing" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Procedimiento para compilar el servicio WCF de procesamiento de pedidos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderProcessingService y seleccione Volver a generar. Asegúrese de que el proyecto se compile correctamente en la ventana Resultados.

Procedimiento para probar el servicio WCF de procesamiento de pedidos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderProcessingService y seleccione Ver en el explorador. Se abrirá una ventana de Internet Explorer con los archivos del directorio.

  2. En la ventana de Internet Explorer, haga clic en OrderProcessing.svc. Asegúrese de no recibir ningún error.

Desarrollo del servicio WCF de envío

El servicio de envío es un servicio WCF que llama a un almacén de SQL Server. En realidad, en la simulación no se realiza ninguna llamada a base de datos.

Procedimiento para agregar un nuevo proyecto de aplicación de servicio de WCF a la solución

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en la solución OrderService, seleccione Agregar y, a continuación, Nuevo proyecto.

  2. En Agregar nuevo proyecto, seleccione o especifique los valores siguientes y haga clic en Aceptar.

    Propiedad Valor

    Tipos de proyecto

    Visual C#/Web

    Plantillas

    Aplicación del servicio de WCF

    Nombre

    ShippingService

    Ubicación

    C:\DublinTutorial\OrderServiceSolution\OrderService

  3. En el Explorador de soluciones, amplíe ShippingService, haga clic con el botón secundario del mouse en el archivo IService1.cs y, a continuación, seleccione Eliminar.

  4. Haga clic en Aceptar para confirmar que desea eliminar el archivo de forma permanente.

  5. En el Explorador de soluciones, amplíe ShippingService, haga clic con el botón secundario del mouse en Service1.svc y, a continuación, seleccione Eliminar.

  6. Haga clic en Aceptar para confirmar que desea eliminar el archivo de forma permanente.

Se define un contrato de servicio denominado IShipping, que contiene dos contratos de operación: ShipOrder y CancelShipping.

Procedimiento para definir el contrato de servicio WCF de envío

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en ShippingService, seleccione Agregar y, a continuación, Nuevo elemento.

  2. En Agregar nuevo elemento - ShippingService, seleccione o especifique los valores siguientes y haga clic en Agregar.

    Propiedad Valor

    Categorías

    Visual C#/Web

    Plantilla

    Servicio WCF

    Nombre

    Shipping.svc

    Se agregan dos archivos al proyecto: IShipping.cs y Shipping.svc.

  3. En el Explorador de soluciones, haga doble clic en el archivo IShipping.cs para abrirlo.

  4. Haga clic con el botón secundario del mouse en el espacio de nombres ShippingService, haga clic en Refactorizar y, a continuación, en Cambiar nombre para abrir el cuadro de diálogo Cambiar nombre.

  5. En Nombre nuevo, escriba Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService y haga clic en Aceptar.

  6. Haga clic en Aplicar y, a continuación, en .

  7. Modifique el código fuente para que tenga este aspecto:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService
    {
        [ServiceContract]
        public interface IShipping
        {
            [OperationContract]
            string ShipOrder(string poID);
    
            [OperationContract]
            string CancelShipping(string poID);
        }
    }
    

Procedimiento para implementar el contrato de servicio WCF de envío

  1. En el Explorador de soluciones, haga doble clic en el archivo Shipping.svc para abrirlo.

  2. Modifique el código fuente para que tenga este aspecto:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService
    {
        class WorkItem
        {
            private Thread workThread;
            private object workItemLock;
            private bool completeFlag;
    
            public Thread WorkThread { get { return workThread; } set { workThread = value; } }
            public object WorkItemLock { get { return workItemLock; } }
            public bool CompleteFlag { get { return completeFlag; } }
    
            public WorkItem(Thread WorkThread)
            {
                workThread = WorkThread;
                workItemLock = new object();
                completeFlag = false;
            }
    
            public void Complete()
            {
                completeFlag = true;
            }
        }
    
        public class Shipping : IShipping
        {
            private static Dictionary<String, WorkItem> WorkItemMap = new Dictionary<String, WorkItem>();
    
            public string ShipOrder(string poID)
            {
                //run the code from a different thread to simulate asynchronized call
                ThreadPool.QueueUserWorkItem(SendShippingResult, poID);
                return ("The request for processing order[" + poID + "] has been received.");
            }
    
            private void SendShippingResult(object state)
            {
                string poID = state.ToString();
    
                WorkItem workItem = new WorkItem(Thread.CurrentThread);
                WorkItemMap.Add(poID, workItem);
    
                //Simulating the order processing process
                Thread.Sleep(60000);
    
                //The following portion will be uncommented after referencing OrderWorkflowService
                //OrderWorkflowService.ShippingServiceResult reply = new OrderWorkflowService.ShippingServiceResult();
                //reply.POID = poID;
                //reply.Message = "The order has been shipped.";
    
                //lock (workItem.WorkItemLock)
                //{
                //    using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
                //    {
                //        client.SubmitShippingResult(reply);
                //    }
    
                //    workItem.Complete();
                //    WorkItemMap.Remove(poID);
                //}
            }
    
            public string CancelShipping(string poID)
            {
                string ret = "Cancel unavailable for this order.";
    
                //=====================================================//
                //===[ Attempt to get a work item for the order Id 
                //=====================================================//
                WorkItem workItem;
                if (WorkItemMap.TryGetValue(poID, out workItem) == true)
                {
                    //===========================================================
                    //=== Slight race condition here. Workitem could complete
                    //=== before we aquire its lock. So we check the          
                    //=== completion flag inside the lock.                    
                    //===========================================================
                    lock (workItem.WorkItemLock)
                    {
                        if ((!workItem.CompleteFlag) && (workItem.WorkThread.IsAlive))
                        {
                            workItem.WorkThread.Abort();
                            WorkItemMap.Remove(poID);
                            ret = "The shipping process has been terminated successfully.";
                        }
                    }
                }
                return ret;
            }
        }
    }
    

En este archivo de configuración, se definen dos extremos.

Procedimiento para configurar el servicio WCF de envío mediante un archivo de configuración

  1. En el Explorador de soluciones, amplíe ShippingService y, a continuación, haga doble clic en el archivo Web.config para abrirlo. Agregue una etiqueta <services> dentro de la etiqueta <system.serviceModel>:

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Shipping">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.IShipping" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Procedimiento para compilar el servicio WCF de envío

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto ShippingService y seleccione Volver a generar. Asegúrese de que el proyecto se compile correctamente en la ventana Resultados.

Desarrollo del servicio WF de flujo de trabajo de pedidos

La aplicación de servicio de flujo de trabajo de pedido constituye la mayor parte del servicio y orquestra todo el proceso empresarial: recibe un pedido de compra, llama a OrderProcessingService y a ShippingService y, finalmente, envía un mensaje de correo electrónico al cliente sobre el estado del pedido de compra.

Procedimiento para agregar un nuevo proyecto de aplicación de servicio de flujo de trabajo WCF a la solución

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en la solución OrderService, seleccione Agregar y, a continuación, Nuevo proyecto.

  2. En Agregar nuevo proyecto, seleccione o especifique los valores siguientes y haga clic en Aceptar.

    Propiedad Valor

    Tipos de proyecto

    Visual C#/Flujo de trabajo

    Plantillas

    Aplicación del servicio de flujo de trabajo de WCF

    Nombre

    OrderWorkflowService

    Ubicación

    C:\DublinTutorial\OrderServiceSolution\OrderService

OrderWorkflowService consume OrderProcessingService y ShippingService. Debe hacer referencia a los dos servicios.

Procedimiento para agregar las referencias de servicio

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderWorkflowService y, a continuación, seleccione Agregar referencia de servicio.

  2. En Agregar referencia de servicio, haga clic en Detectar. Visual Studio detectará ambos servicios.

  3. Especifique y seleccione los valores siguientes y haga clic en Aceptar para crear la referencia de servicio.

    Propiedad Valor

    Servicios

    OrderProcessing.svc

    Espacio de nombres

    OrderProcessService

  4. Repita los pasos para agregar otra referencia de servicio con los siguientes valores:

    Propiedad Valor

    Servicios

    Envío

    Espacio de nombres

    ShippingService

Para simular el envío de notificaciones por correo electrónico, es necesario definir una actividad de flujo de trabajo personalizada.

Procedimiento para crear una actividad de código de flujo de trabajo

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderWorkflowService, seleccione Agregar y, a continuación, Nuevo elemento.

  2. En Agregar nuevo elemento - OrderWorkflowService, seleccione o especifique los valores siguientes y haga clic en Agregar.

    Propiedad Valor

    Categorías

    Visual C#/Flujo de trabajo

    Plantilla

    Actividad de código

    Nombre

    SendNotification.cs

  3. En el Explorador de soluciones, haga doble clic en el archivo SendNotification.cs para abrirlo.

  4. Haga clic con el botón secundario del mouse en el espacio de nombres OrderWorkflowService, seleccione en Refactorizar y, a continuación, Cambiar nombre para abrir el cuadro de diálogo Cambiar nombre.

  5. En Nombre nuevo, escriba Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService y haga clic en Aceptar.

  6. Haga clic en Aplicar y, a continuación, en .

  7. Modifique el código fuente para que tenga este aspecto:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Activities;
    using System.IO;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService
    {
        public class SendNotification : CodeActivity
        {
            InArgument<string> to;
            InArgument<string> subject;
            InArgument<string> body;
            string pathRoot = @"C:\DublinTutorial\Inbox\";
    
            public InArgument<string> To { get { return this.to; } set { this.to = value; } }
            public InArgument<string> Subject { get { return this.subject; } set { this.subject = value; } }
            public InArgument<string> Body { get { return this.body; } set { this.body = value; } }
            public SendNotification() { }
    
            public SendNotification(InArgument<string> To, InArgument<string> Subject, InArgument<string> Body)
            {
                this.to = To; this.subject = Subject; this.body = Body;
            }
    
            protected override void Execute(CodeActivityContext context)
            {
                string filename;
                string content;
    
                try
                {
                    filename = this.to.Get<String>(context) + "~~" + this.subject.Get<string>(context) + "_" + DateTime.Now.ToFileTime() + ".txt";
                    content = String.Format("To: {0}" + Environment.NewLine
                        + "From: {1}" + Environment.NewLine
                        + "Subject: {2}" + Environment.NewLine
                        + Environment.NewLine
                        + "{3}",
                        this.to.Get<String>(context), "CustomerRelations@Contoso.com", this.subject.Get<String>(context), this.body.Get<String>(context));
    
                    File.WriteAllText((pathRoot + filename), content);
                }
                catch (Exception Ex)
                {
                    context.SetValue(Body, Ex.Message);
                }
    
            }
        }
    }
    

    Observe que la ruta de acceso está codificada como “C:\DublinTutorial\Inbox\”.

En el procedimiento siguiente, definirá los tipos de datos. Estos tipos de datos se usan para que OrderProcessingService y ShippingService devuelvan resultados a OrderWorkflowService.

Procedimiento para definir tipos de datos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderWorkflowService, seleccione Agregar y, a continuación, Nuevo elemento.

  2. En Agregar nuevo elemento - OrderWorkflowService, seleccione o especifique los valores siguientes y haga clic en Agregar.

    Propiedad Valor

    Categorías

    Visual C#/Código

    Plantilla

    Archivo de código

    Nombre

    DataTypes.cs

  3. En el Explorador de soluciones, haga doble clic en el archivo DataTypes.cs para abrirlo.

  4. Modifique el código fuente para que tenga este aspecto:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService
    {
        [DataContract]
        public class ProcessServiceResult
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string Message;
        }
    
        [DataContract]
        public class ShippingServiceResult
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string Message;
        }
    }
    
  5. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderWorkflowService y, a continuación, seleccione Volver a generar. Genere el proyecto para que la actividad de código esté accesible desde el flujo de trabajo que desarrollará en el paso siguiente. La compilación también puede exponer los extremos del servicio WCF de referencia al flujo de trabajo.

El paso siguiente consiste en definir el flujo de trabajo. El flujo de trabajo contiene varios estados. Para empezar, defina los estados y, a continuación, sus detalles. Cada parte del desarrollo puede contener los pasos siguientes:

  1. Composición del flujo de trabajo mediante actividades.

  2. Definición de variables.

  3. Configuración de actividades.

Procedimiento para definir el flujo de trabajo

  1. En el Explorador de soluciones, amplíe OrderWorkflowService, haga clic con el botón secundario del mouse en Service1.xamlx y, a continuación, haga clic en Cambiar nombre. Cambie el nombre del archivo a OrderWorkflow.xamlx.

  2. En el Explorador de soluciones, haga doble clic en el archivo OrderWorkflow.xamlx para abrirlo. El servicio secuencial incluye dos actividades: ReceiveRequest y SendResponse.

  3. Haga clic con el botón secundario del mouse en la actividad Sequential Service y, a continuación, haga clic en Eliminar.

  4. En el flujo de trabajo, haga clic en Colocar actividad aquí y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    configurationName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow

    Name

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow

  5. Haga clic en Cuadro de herramientas en el lateral izquierdo de la ventana para abrir el panel Cuadro de herramientas y ánclelo en el lateral izquierdo de la ventana.

  6. Arrastre las siguientes actividades del Cuadro de herramientas a la sección “Colocar actividad aquí” del flujo de trabajo.

    Categoría Actividad Nota

    Diagrama de flujo

    Flowchart

    La actividad Flowchart es una actividad compuesta que, de forma predeterminada, incluye un inicio. En los pasos siguientes agregará más actividades.

  7. Arrastre las siguientes actividades del Cuadro de herramientas al flujo de trabajo en este orden:

    Categoría Actividad Nota

    Messaging

    ReceiveAndSendReply

    Estado “Wait for order”.

    Control Flow

    Sequence

    Contiene el segundo estado “Order opened”.

    Diagrama de flujo

    FlowDecision

    La actividad FlowDecision facilita la transición entre estados.

    Control Flow

    Sequence

    Contiene el tercer estado “Order processed”.

    Diagrama de flujo

    FlowDecision

    La actividad FlowDecision facilita la transición entre estados.

    Control Flow

    Sequence

    Contiene el último estado “Order completed”.

  8. Use el puntero del mouse para conectar las actividades como se ilustra a continuación:

    67e7c9dd-77e7-43be-ad5a-797b3b46f6e8

  9. Haga clic en Variables en la parte inferior del flujo de trabajo para abrir el panel Variables.

  10. En el panel Variables, haga clic en Crear variable y, a continuación, cree las variables siguientes:

    Nombre de variable Tipo de variable Ámbito Nota

    poID

    String

    Diagrama de flujo

    poID es un número de GUID. También se usa para la correlación.

    isProcessed

    Boolean

    Diagrama de flujo

    Indicador que muestra si el pedido se ha procesado correctamente.

    isShipped

    Boolean

    Diagrama de flujo

    Indicador que muestra si el pedido se ha enviado.

    isUpdated

    Boolean

    Diagrama de flujo

    Indicador que muestra si el cliente ha actualizado el pedido.

    po

    PurchaseOrder

    Diagrama de flujo

    Tipo de dato personalizado definido en OrderProcessingService. Contiene información del PC.

    poUpdate

    PurchaseOrder

    Diagrama de flujo

    Contiene información de PC actualizada cuando el cliente desea actualizar el PC.

    correlationorderWorkflow

    CorrelationHandle

    Diagrama de flujo

    Controlador de correlación que se usa para conectar el cliente al servicio y el servicio a OrderProcessService y ShippingService.

    A continuación se incluye una captura de pantalla de las variables creadas:

    9208977f-710c-460f-afd8-5c6bd8a792d9

  11. En el flujo de trabajo, haga clic en la actividad Flowchart y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Order service

  12. En el flujo de trabajo, haga clic en la primera actividad Sequence y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Wait for order

  13. En el flujo de trabajo, haga clic en la segunda actividad Sequence y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Order opened

  14. En el flujo de trabajo, haga clic en la tercera actividad Sequence y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Order processed

  15. En el flujo de trabajo, haga clic en la cuarta actividad Sequence y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Order completed

  16. En el flujo de trabajo, haga clic en la primera actividad FlowDecision y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Condition

    isProcessed

    FalseLabel

    Updated

    TrueLabel

    Processed

  17. En el flujo de trabajo, haga clic en la segunda actividad FlowDecision y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Condition

    isShipped

    FalseLabel

    Updated

    TrueLabel

    Shipped

    Ha definido la estructura principal del flujo de trabajo de la máquina de estados. A continuación definirá los estados.

  18. En el flujo de trabajo, haga doble clic en Wait for order. Observe que la ruta de acceso se muestra bajo la pestaña. Haga clic en Order service para volver a la página que contiene el flujo de trabajo de la máquina de estados.

  19. Arrastre las siguientes actividades del Cuadro de herramientas al flujo de trabajo en este orden:

    Categoría Actividad Nota

    Primitives

    Assign

    La actividad Assign obtiene un identificador de pedido (GUID) para el pedido.

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowSerivce

    SendNotification

    Esta actividad personalizada envía notificaciones por correo electrónico al cliente.

    Primitives

    Assign

    La actividad Assign se usa para poder realizar el seguimiento del producto del pedido de compra.

    Primitives

    Assign

    La actividad Assign se usa para poder realizar el seguimiento de la cantidad del pedido de compra.

  20. Reorganice las actividades para que tengan este aspecto:

    Esperar actividades de estado del pedido

  21. Haga clic en Variables en la parte inferior del flujo de trabajo para abrir el panel Variables.

  22. En el panel Variables, haga clic en Crear variable y, a continuación, cree las variables siguientes:

    Nombre de variable Tipo de variable Ámbito Nota

    product

    String

    Wait for order

    AppFabric puede realizar el seguimiento de variables de flujo de trabajo. Esta variable se crea para poder realizar el seguimiento del nombre del producto.

    quantity

    Int32

    Wait for order

    Esta variable tiene una finalidad de seguimiento.

  23. En el flujo de trabajo, haga clic en la actividad Receive y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data: po; Message type: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.Purchaseorder

    DisplayName

    Receive PO

    OperationName

    SubmitPO

    SerivceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (seleccionado)

  24. En el flujo de trabajo, haga clic en la primera actividad Assign y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Assign PO ID

    To

    po.POID

    Value

    System.Guid.NewGuid().ToString()

  25. En el flujo de trabajo, haga clic en la actividad SendReplyToReceive y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data: po.POID; Message type: string

    CorrelationInitializers

    CorrelationOrderWorkflow;Query correlation initialize; key1=sm:body()/xg0:string

    237be300-a94d-4b8e-a707-83f4d2041f6e

    Nota

    Lo que acaba de hacer se denomina correlación. Este flujo de trabajo tiene siete actividades de recepción: una que recibe el pedido de compra, una que recibe el resultado del servicio de proceso, una que recibe el resultado del servicio de envío, dos que reciben actualizaciones de clientes y dos que reciben cancelaciones de clientes. Después de recibir el pedido de compra, el servicio de flujo de trabajo genera un número de GUID como número de pedido. Imagine que el servicio de flujo de trabajo recibe muchos pedidos de compra a la vez. El motor de flujo de trabajo crea una instancia de flujo de trabajo para cada solicitud de pedido de compra. El motor del flujo de trabajo necesita asociar (o correlacionar) las otras seis solicitudes a las instancias de flujo de trabajo. Para conseguirlo, el motor de flujo de trabajo necesita un identificador único para cada correlación. En esta muestra, este identificador único es el número de pedido (GUID). En la primera actividad SendReplyToReceive, se define CorrelationInitializer. A continuación, se elige el tipo de consulta de iniciador de correlación, lo que significa que el identificador único se encuentra en el mensaje que se pasa a la actividad de recepción. También se especifica xPath en el campo. Además del inicializador de correlación, en el campo CorrelateWith también debe especificar un controlador de correlación. Un controlador de correlación es un contenedor para datos de correlación que permite recuperar estos datos desde cualquier punto del flujo de trabajo. En las recepciones subsiguientes, se especifica el mismo controlador de correlación. En los campos CorrelateOn, se especifica la forma de recuperar el número de pedido del mensaje recibido.

  26. En el flujo de trabajo, haga clic en la actividad SendNotification y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "We have received your order.  Your order number is " + po.POID

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Received"

    To

    po.EmailAddress

  27. En el flujo de trabajo, haga clic en la segunda actividad Assign y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Assign product name

    To

    proudct

    Value

    po.Description

  28. En el flujo de trabajo, haga clic en la tercera actividad Assign y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Assign quantity

    To

    quantity

    Value

    po.Quantity

    Ha acabado de implementar el estado Wait for order.

  29. Bajo el nombre de la pestaña, haga clic en Order service para mostrar la actividad de diagrama de flujo “Order service”.

  30. En el flujo de trabajo, haga doble clic en la actividad de Sequence Order opened para implementar el estado.

  31. Arrastre las siguientes actividades del Cuadro de herramientas al flujo de trabajo en este orden:

    Categoría Actividad Nota

    Primitives

    Assign

    Control Flow

    Parallel

  32. Arrastre la siguiente actividad dentro de la actividad Parallel:

    Categoría Actividad Nota

    Control Flow

    Sequence

  33. Arrastre la siguiente actividad dentro de la actividad Sequence:

    Category Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    ProcessOrder

    Runtime

    Persist

    Messaging

    Receive

    Microsoft.Samples.Dublin.Tutorials.OrderService.orderWorkflowService

    SendNotification

    Primitives

    Assign

  34. Arrastre la siguiente actividad dentro de la actividad Parallel y a la derecha de la actividad Sequence existente:

    Categoría Actividad Nota

    Messaging

    ReceiveAndSendReply

    La actividad ReceiveAndSendReply es una actividad compuesta con una actividad Sequence que contiene las actividades Receive y SendReplyToReceive.

  35. Arrastre las actividades siguientes dentro de la actividad Sequence agregada, bajo las actividades Receive y SendReplyToReceive:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    CancelOrderProcess

    Control Flow

    If

  36. Arrastre la siguiente actividad dentro de la sección Then de la actividad If:

    Categoría Actividad Nota

    Control Flow

    Sequence

  37. Arrastre las actividades siguientes dentro de la actividad Sequence agregada:

    Categoría Actividad Nota

    Primitives

    Assign

    Primitives

    Assign

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

  38. Arrastre la siguiente actividad dentro de la sección Else de la actividad If:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

  39. Arrastre la siguiente actividad dentro de la actividad Parallel para convertirla en la sección situada más a la derecha:

    Categoría Actividad Nota

    Messaging

    ReceiveAndSendReply

  40. Arrastre las actividades siguientes dentro de la actividad Sequence agregada y bajo las actividades Receive y SendReplyToReceive:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    CancelOrderProcess

    Control Flow

    If

  41. Arrastre la siguiente actividad dentro de la sección Then de la actividad If:

    Categoría Actividad Nota

    Control Flow

    Sequence

  42. Arrastre las siguientes actividades dentro de la actividad Sequence agregada:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    Runtime

    TerminateWorkflow

  43. Arrastre la siguiente actividad dentro de la sección Else de la actividad If:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    Tras agregar las actividades, el estado Order Opened tiene el siguiente aspecto:

    Estado de pedido abierto

  44. Haga clic en la actividad Sequence de la izquierda de la actividad Parallel y, a continuación, haga clic en Variables en la parte inferior del flujo de trabajo para abrir el panel Variables.

  45. En el panel Variables, haga clic en Crear variable y, a continuación, cree las variables siguientes:

    Nombre de variable Tipo de variable Ámbito Nota

    cancelOrderProcessAcknowledgement

    String

    Parallel

    ProcessServiceResult

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ProcessServiceResult

    Sequence

    processServiceAcknowledgement

    String

    Sequence

  46. En el flujo de trabajo, haga clic en la actividad Assign situada al principio de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Initialize isUpdated

    To

    isUpdated

    Value

    False

  47. En el flujo de trabajo, haga clic en la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Completion

    isUpdated Or isProcessed

    DisplayName

    Process order

  48. En el flujo de trabajo, haga clic en la actividad Sequence situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Processing

  49. En el flujo de trabajo, haga clic en la actividad ProcessOrder situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Process order

    po

    po

    ProcessOrderResult

    processServiceAcknowledgement

  50. En el flujo de trabajo, haga clic en la actividad Receive situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data:processServiceResult; Message type: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ProcessServiceResult

    DisplayName

    Receive process result

    OperationName

    SubmitProcessResult

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Clear)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; XPath Queries: key1=sm:body()/xg0:ProcessServiceResult/sg0:POID

    CorrelationWith

    correlationOrderWorkflow

  51. En el flujo de trabajo, haga clic en la actividad SendNotification situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Order with order#" + po.POID + " has been processed, and is ready for shipping."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Processed"

    To

    po.EmailAddress
  52. En el flujo de trabajo, haga clic en la actividad Assign situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Set isProcessed flag

    To

    isProcessed

    Value

    True

    Ha acabado de configurar la sección izquierda de la actividad Parallel.

  53. En el flujo de trabajo, haga clic en la actividad Sequence situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Waiting for update

  54. En el flujo de trabajo, haga clic en la actividad Receive situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data:poUpdate; Message type: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.PurchaseOrder

    DisplayName

    Receive update

    OperationName

    SubmitUpdate

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Clear)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; XPath Queries: key1=sm:body()/xg0:PurchaseOrder/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  55. En el flujo de trabajo, haga clic en la actividad SendReplyToReceive situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data: “PO update received”; Message type: String

    DisplayName

    Acknowledge receiving update

  56. En el flujo de trabajo, haga clic en la actividad CancelOrderProcess situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    CancelOrderProcessResult

    cancelOrderProcessAcknowledgement

    DisplayName

    Cancel order processing

    orderID

    po.POID
  57. En el flujo de trabajo, haga clic en la actividad If situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Condition

    cancelOrderProcessAcknowledgement = "The order process has been terminated successfully."

    DisplayName

    Check cancellation status

  58. En el flujo de trabajo, haga clic en la actividad Sequence de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Cancellation succeed sequence

  59. En el flujo de trabajo, haga clic en la primera actividad Assign de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Refresh PO

    To

    po

    Value

    poUpdate
  60. En el flujo de trabajo, haga clic en la segunda actividad Assign de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Set isUpdated flag

    To

    isUpdated

    Value

    True
  61. En el flujo de trabajo, haga clic en la actividad SendNotification de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order has updated upon your request. The order is under processing."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Updated (by customer)"

    To

    po.EmailAddress
  62. En el flujo de trabajo, haga clic en la actividad SendNotification de la sección Else de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order update request cannot be processed. Please try again."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Update (by customer) Failed"

    To

    po.EmailAddress

    Ha acabado de configurar la sección central de la actividad Parallel.

  63. En el flujo de trabajo, haga clic en la actividad Sequence situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Waiting for cancellation

  64. En el flujo de trabajo, haga clic en la actividad Receive situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data:poID; Message type:String

    DisplayName

    Receive cancellation

    OperationName

    SubmitCancellation

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Clear)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; XPath Queries: key1=sm:body()/xg0:string

    CorrelationWith

    correlationOrderWorkflow

  65. En el flujo de trabajo, haga clic en la actividad SendReplyToReceive situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data: “PO cancellation received”; Message type: String

    DisplayName

    Acknowledge receiving cancellation

  66. En el flujo de trabajo, haga clic en la actividad CancelOrderProcess situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    CancelOrderProcessResult

    cancelOrderProcessAcknowledgement

    DisplayName

    Cancel order processing

    orderID

    po.POID
  67. En el flujo de trabajo, haga clic en la actividad If situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Condition

    cancelOrderProcessAcknowledgement = "The order process has been terminated successfully."

    DisplayName

    Check cancellation status

  68. En el flujo de trabajo, haga clic en la actividad Sequence de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Cancellation succeed sequence

  69. En el flujo de trabajo, haga clic en la actividad SendNotification de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order has been cancelled upon your request."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancelled (by customer)"

    To

    po.EmailAddress
  70. En el flujo de trabajo, haga clic en la actividad TerminateWorkflow de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Terminate workflow

    Reason

    “Client cancellation”
  71. En el flujo de trabajo, haga clic en la segunda actividad SendNotification de la sección Else de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order cancellation request cannot be processed. Please try again."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancellation(by customer) Failed"

    To

    po.EmailAddress

    Ha acabado de configurar la sección derecha de la actividad Parallel.

  72. Bajo el nombre de la pestaña, haga clic en Order service para mostrar la actividad de diagrama de flujo “Order service”.

  73. En el flujo de trabajo, haga doble clic en la actividad de Sequence Order processed para implementar el estado.

  74. Arrastre las siguientes actividades del Cuadro de herramientas al flujo de trabajo en este orden:

    Categoría Actividad Nota

    Primitives

    Assign

    Control Flow

    Parallel

  75. Arrastre la siguiente actividad dentro de la actividad Parallel:

    Categoría Actividad Nota

    Control Flow

    Sequence

  76. Arrastre la siguiente actividad dentro de la actividad Sequence:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    ShipOrder

    Runtime

    Persist

    Messaging

    Receive

    Primitives

    Assign

  77. Arrastre la siguiente actividad dentro de la actividad Parallel y a la derecha de la actividad Sequence existente:

    Categoría Actividad Nota

    Messaging

    ReceiveAndSendReply

    La actividad ReceiveAndSendReply es una actividad compuesta con una actividad Sequence que contiene las actividades Receive y SendReplyToReceive.

  78. Arrastre las actividades siguientes dentro de la actividad Sequence agregada y bajo las actividades Receive y SendReplyToReceive:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    CancelShipping

    Control Flow

    If

  79. Arrastre la siguiente actividad dentro de la sección Then de la actividad If:

    Categoría Actividad Nota

    Control Flow

    Sequence

  80. Arrastre las siguientes actividades dentro de la actividad Sequence agregada:

    Categoría Actividad Nota

    Primitives

    Assign

    Primitives

    Assign

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  81. Arrastre la siguiente actividad dentro de la sección Else de la actividad If:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  82. Arrastre la siguiente actividad dentro de la actividad Parallel para convertirla en la sección situada más a la derecha:

    Categoría Actividad Nota

    Messaging

    ReceiveAndSendReply

  83. Arrastre las actividades siguientes dentro de la actividad Sequence agregada y bajo las actividades Receive y SendReplyToReceive:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    CancelShipping

    Control Flow

    If

  84. Arrastre la siguiente actividad dentro de la sección Then de la actividad If:

    Categoría Actividad Nota

    Control Flow

    Sequence

  85. Arrastre las siguientes actividades dentro de la actividad Sequence agregada:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

    Runtime

    TerminateWorkflow

  86. Arrastre la siguiente actividad dentro de la sección Else de la actividad If:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    Tras agregar las actividades, el estado Order Processed tiene el siguiente aspecto:

    Estado de pedido procesado

  87. Haga clic en la actividad Sequence de la izquierda de la actividad Parallel y, a continuación, haga clic en Variables en la parte inferior del flujo de trabajo para abrir el panel Variables.

  88. En el panel Variables, haga clic en Crear variable y, a continuación, cree las variables siguientes:

    Nombre de variable Tipo de variable Ámbito Nota

    cancelShippingAcknowledgement

    String

    Parallel

    ShippingServiceResult

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ShippingServiceResult

    Sequence

    shippingServiceAcknowledgement

    String

    Sequence

  89. En el flujo de trabajo, haga clic en la actividad Assign situada al principio de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Initialize isUpdated

    To

    isUpdated

    Value

    False

  90. En el flujo de trabajo, haga clic en la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Completion

    isUpdated Or isShipped

    DisplayName

    Ship order

  91. En el flujo de trabajo, haga clic en la actividad Sequence situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Shipping

  92. En el flujo de trabajo, haga clic en la actividad ShipOrder situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Ship order

    poID

    po.POID

    ShipOrderResult

    shippingServiceAcknowledgement

  93. En el flujo de trabajo, haga clic en la actividad Receive situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data:shippingServiceResult; Message type: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ShippingServiceResult

    DisplayName

    Receive shipping result

    OperationName

    SubmitShippingResult

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Clear)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; XPath Queries: key1=sm:body()/xg0:ShippingServiceResult/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  94. En el flujo de trabajo, haga clic en la actividad Assign situada a la izquierda de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Set isShipped flag

    To

    isShipped

    Value

    True

    Ha acabado de configurar la sección izquierda de la actividad Parallel.

  95. En el flujo de trabajo, haga clic en la actividad Sequence situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Waiting for update

  96. En el flujo de trabajo, haga clic en la actividad Receive situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data:poUpdate; Message type: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.PurchaseOrder

    DisplayName

    Receive update

    OperationName

    SubmitUpdate

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Clear)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; XPath Queries: key1=sm:body()/xg0:PurchaseOrder/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  97. En el flujo de trabajo, haga clic en la actividad SendReplyToReceive situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data: “PO update received”; Message type: String

    DisplayName

    Acknowledge receiving update

  98. En el flujo de trabajo, haga clic en la actividad CancelShipping situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    CancelShippingResult

    cancelShippingAcknowledgement

    DisplayName

    Cancel shipping

    orderID

    poUpdate.POID
  99. En el flujo de trabajo, haga clic en la actividad If situada en el centro de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Condition

    cancelShippingAcknowledgement = "The shipping process has been terminated successfully."

    DisplayName

    Check cancellation status

  100. En el flujo de trabajo, haga clic en la actividad Sequence de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Cancellation succeed sequence

  101. En el flujo de trabajo, haga clic en la primera actividad Assign de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Refresh PO

    To

    po

    Value

    poUpdate
  102. En el flujo de trabajo, haga clic en la segunda actividad Assign de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Set isUpdated flag

    To

    isUpdated

    Value

    True
  103. En el flujo de trabajo, haga clic en la actividad SendNotification de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order has updated upon your request. The order is under processing."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Updated (by customer)"

    To

    po.EmailAddress
  104. En el flujo de trabajo, haga clic en la actividad SendNotification de la sección Else de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order update request cannot be processed. The order has been shipped."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Update (by customer) Failed"

    To

    po.EmailAddress

    Ha acabado de configurar la sección central de la actividad Parallel.

  105. En el flujo de trabajo, haga clic en la actividad Sequence situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Waiting for cancellation

  106. En el flujo de trabajo, haga clic en la actividad Receive situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data:poID; Message type:String

    DisplayName

    Receive cancellation

    OperationName

    SubmitCancellation

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Clear)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; XPath Queries: key1=sm:body()/xg0:string

    CorrelationWith

    correlationOrderWorkflow

  107. En el flujo de trabajo, haga clic en la actividad SendReplyToReceive situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Content

    Message; Message data: “PO cancellation received”; Message type: String

    DisplayName

    Acknowledge receiving cancellation

  108. En el flujo de trabajo, haga clic en la actividad CancelShipping situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    CancelshippingResult

    cancelShippingAcknowledgement

    DisplayName

    Cancel shipping

    poID

    po.POID
  109. En el flujo de trabajo, haga clic en la actividad If situada a la derecha de la actividad Parallel y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Condition

    cancelShippingAcknowledgement = "The shipping process has been terminated successfully."

    DisplayName

    Check cancellation status

  110. En el flujo de trabajo, haga clic en la actividad Sequence de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Cancellation succeed sequence

  111. En el flujo de trabajo, haga clic en la actividad SendNotification de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "We are sorry you chose to cancel your order. If there is anything we can do to help you with our order process or with our products or services please do not hesitate to contact us."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancelled (by cusotmer)"

    To

    po.EmailAddress
  112. En el flujo de trabajo, haga clic en la actividad TerminateWorkflow de la sección Then de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    DisplayName

    Terminate workflow

    Reason

    “Client cancellation”
  113. En el flujo de trabajo, haga clic en la segunda actividad SendNotification de la sección Else de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order cancellation request cannot be processed. The order has been shipped.

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancellation(by customer) Failed"

    To

    po.EmailAddress

    Ha acabado de configurar la sección derecha de la actividad Parallel.

  114. Bajo el nombre de la pestaña, haga clic en Order service para mostrar la actividad de diagrama de flujo “Order service”.

  115. En el flujo de trabajo, haga doble clic en la actividad de Sequence Order completed para implementar el estado.

  116. Arrastre las siguientes actividades del Cuadro de herramientas al flujo de trabajo en este orden:

    Categoría Actividad Nota

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  117. En el flujo de trabajo, haga clic en la segunda actividad SendNotification de la sección Else de la actividad If y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Body

    "Your order has been shipped.  Thank you for shopping at contoso.com."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~ Order Shipped"

    To

    po.EmailAddress

    Ha finalizado la implementación del flujo de trabajo.

En este archivo de configuración, se definen dos extremos y un elemento de comportamiento.

Procedimiento para configurar el servicio de flujo de trabajo de pedidos mediante un archivo de configuración

  1. En el Explorador de soluciones, amplíe OrderWorkflowService y, a continuación, haga doble clic en el archivo Web.config para abrirlo.

  2. Agregue una etiqueta <services> dentro de la etiqueta <system.serviceModel>.

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Procedimiento para compilar el servicio de flujo de trabajo de pedidos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderWorkflowService y seleccione Volver a generar. Asegúrese de que el proyecto se compile correctamente en la ventana Resultados.

Finalización del servicio de procesamiento de pedidos

OrderProcessingService y OrderWorkflowService se referencian entre sí. De modo que, después de finalizar OrderWorkflowService, debe finalizar OrderProcessingService.

Procedimiento para agregar las referencias de servicio

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderProcessingService y, a continuación, seleccione Agregar referencia de servicio.

  2. En Agregar referencia de servicio, haga clic en Detectar. Visual Studio detectará ambos servicios.

  3. Especifique y seleccione los valores siguientes y haga clic en Aceptar para crear la referencia de servicio.

    Propiedad Valor

    Services

    OrderWorkflow.xamlx

    Namespace

    OrderWorkflowService

Procedimiento para modificar OrderProcess.svc

  1. En el Explorador de soluciones, amplíe OrderProcessingService y, a continuación, haga doble clic en el archivo OrderProcessing.svc para abrirlo.

  2. Quite las marcas de comentarios de la sección situada dentro de la función SendProcessResult para que tenga este aspecto:

    
    private void SendProcessResult(object state)
    {
        PurchaseOrder po = (PurchaseOrder)state;
    
        WorkItem workItem = new WorkItem(Thread.CurrentThread);
        WorkItemMap.Add(po.POID, workItem);
    
        //Simulating the order processing process
        Thread.Sleep(120000);
    
        //The following portion will be uncommented after referencing OrderWorkflowService
        OrderWorkflowService.ProcessServiceResult reply = new OrderWorkflowService.ProcessServiceResult();
        reply.POID = po.POID;
        reply.Message = "The order has been processed successfully.";
    
        lock (workItem.WorkItemLock)
        {
            using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
            {
                client.SubmitProcessResult(reply);
            }
    
            workItem.Complete();
            WorkItemMap.Remove(po.POID);
        }
    
    }
    

Procedimiento para compilar el servicio de procesamiento de pedido

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderProcessingService y seleccione Volver a generar. Asegúrese de que el proyecto se compile correctamente en la ventana Resultados.

Finalización del servicio de envío

ShippingService y OrderWorkflowService se referencian entre sí. De modo que, después de finalizar OrderWorkflowService, debe finalizar ShippingService.

Procedimiento para agregar las referencias de servicio

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en ShippingService y, a continuación, seleccione Agregar referencia de servicio.

  2. En Agregar referencia de servicio, haga clic en Detectar. Visual Studio detectará ambos servicios.

  3. Especifique y seleccione los valores siguientes y haga clic en Aceptar para crear la referencia de servicio.

    Propiedad Valor

    Services

    OrderWorkflow.xamlx

    Namespace

    OrderWorkflowService

Procedimiento para modificar Shipping.svc

  1. En el Explorador de soluciones, amplíe ShippingService y, a continuación, haga doble clic en el archivo Shipping.svc para abrirlo.

  2. Quite las marcas de comentarios de la sección situada dentro de la función SendShippingResult para que tenga este aspecto:

    private void SendShippingResult(object state)
    {
        string poID = state.ToString();
    
        WorkItem workItem = new WorkItem(Thread.CurrentThread);
        WorkItemMap.Add(poID, workItem);
    
        //Simulating the order processing process
        Thread.Sleep(60000);
    
        //The following portion will be uncommented after referencing OrderWorkflowService
        OrderWorkflowService.ShippingServiceResult reply = new OrderWorkflowService.ShippingServiceResult();
        reply.POID = poID;
        reply.Message = "The order has been shipped.";
    
        lock (workItem.WorkItemLock)
        {
            using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
            {
                client.SubmitShippingResult(reply);
            }
    
            workItem.Complete();
            WorkItemMap.Remove(poID);
        }
    }
    

Procedimiento para compilar el servicio de envío

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto ShippingService y seleccione Volver a generar. Asegúrese de que el proyecto se compile correctamente en la ventana Resultados.

Desarrollo de la aplicación cliente de pedido

En este paso, desarrollará una aplicación cliente de Windows Form.

Procedimiento para agregar un proyecto de aplicación de Windows Form a la solución

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en la solución OrderService, seleccione Agregar y, a continuación, Nuevo proyecto.

  2. En Agregar nuevo proyecto, seleccione o especifique los valores siguientes y haga clic en Aceptar.

    Propiedad Valor

    Tipos de proyecto

    Visual C#/Windows

    Plantillas

    Aplicación de Windows Forms

    Nombre

    OrderClient

    Ubicación

    C:\DublinTutorial\OrderServiceSolution\OrderService

El cliente de pedidos es la interfaz del servicio de flujo de trabajo. Es necesario agregar una referencia de servicio al servicio de flujo de trabajo.

Procedimiento para agregar una referencia de servicio

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderClient y, a continuación, seleccione Agregar referencia de servicio para abrir el cuadro de diálogo Agregar referencia de servicio.

  2. En Agregar referencia de servicio, haga clic en Detectar.

  3. Especifique y seleccione los valores siguientes y haga clic en Aceptar para crear la referencia de servicio.

    Propiedad Valor

    Services

    OrderWorkflow.xamlx

    Namespace

    OrderWorkflowService

Procedimiento para desarrollar un Windows Form

  1. En el Explorador de soluciones, amplíe OrderClient y, a continuación, haga doble clic en el archivo Form1.cs para abrirlo.

  2. Haga clic con el botón secundario del mouse en Form1.cs, seleccione Cambiar nombre y escriba OrderForm.cs.

  3. Haga clic en para confirmar.

  4. En el Cuadro de herramientas, agregue al formulario cuatro controles Label, cinco TextBox y tres Button y alinee los controles para que tengan este aspecto:

    Formulario de pedido para el cliente

  5. En el flujo de trabajo, haga clic en el formulario y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    OrderForm

    Text

    Contoso.com Order Form

  6. En el flujo de trabajo, haga clic en label1 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    lblOrderNumber

    Text

    Order number:

  7. En el flujo de trabajo, haga clic en label2 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    lblEmail

    Text

    Email:

  8. En el flujo de trabajo, haga clic en label3 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    lblDescription

    Text

    Description:

  9. En el flujo de trabajo, haga clic en label4 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    lblQuantity

    Text

    Quantity:

  10. En el flujo de trabajo, haga clic en textbox1 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    txtOrderNumber

    Enabled

    False

  11. En el flujo de trabajo, haga clic en textbox2 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    txtEmail

    Text

    JohnDole@fabrikam.com

  12. En el flujo de trabajo, haga clic en textbox3 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    txtDescription

    Text

    Windows 7

  13. En el flujo de trabajo, haga clic en textbox4 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    txtQuantity

    Text

    10

  14. En el flujo de trabajo, haga clic en textbox5 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    txtStatus

    Anchor

    Bottom, Left, Right

    Enabled

    False

    Text

    “”

  15. En el flujo de trabajo, haga clic en button1 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    btnSubmit

    Anchor

    Bottom, Right

    Text

    Submit

    Click (Under the Event tab)

    btnSubmit_Click

  16. En el flujo de trabajo, haga clic en button2 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    btnUpdate

    Anchor

    Bottom, Right

    Text

    Update

    Click (Under the Event tab)

    btnUpdate_Click

  17. En el flujo de trabajo, haga clic en button3 y defina los siguientes valores en el panel Propiedades.

    Propiedad Valor

    Name

    btnCancel

    Anchor

    Bottom, Right

    Text

    Cancel

    Click (Under the Event tab)

    btnCancel_Click

  18. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderForm.cs y, a continuación, seleccione Ver código.

  19. Haga clic con el botón secundario del mouse en el espacio de nombres OrderClient, haga clic en Refactorizar y, a continuación, en Cambiar nombre para abrir el cuadro de diálogo Cambiar nombre.

  20. En Cambiar nombre, escriba Microsoft.Samples.Dublin.Tutorials.OrderService.OrderClient y haga clic en Aceptar.

  21. Haga clic en Aplicar.

  22. Sustituya el código por el siguiente:

    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;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderClient
    {
        public partial class OrderForm : Form
        {
            //Delegates to make all service calls on a secondary thread
            private delegate void SubmitOrderDelegate();
            private delegate void CancelOrderDelegate();
            private delegate void UpdateOrderDelegate();
            private delegate void CallbackDelegate(string poID, string str);
    
            private SubmitOrderDelegate SubmitOrderHandler;
            private CancelOrderDelegate CancelOrderHandler;
            private UpdateOrderDelegate UpdateOrderHandler;
            private CallbackDelegate CallbackHandler;
    
            public OrderForm()
            {
                InitializeComponent();
            }
    
            private void OrderForm_Load(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
                btnSubmit.Focus();
            }
    
            #region Submit button
            private void btnSubmit_Click(object sender, EventArgs e)
            {
                btnSubmit.Enabled = false;
                btnCancel.Enabled = false;
                btnUpdate.Enabled = false;
                txtEmail.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                SubmitOrderHandler = new SubmitOrderDelegate(this.SubmitOrder);
                SubmitOrderHandler.BeginInvoke(null, null);
            }
    
            private void SubmitOrder()
            {
                string strMessage = "Your order has been received.";
                string strPOID = "";
    
                OrderWorkflowService.PurchaseOrder po = new OrderWorkflowService.PurchaseOrder();
                po.EmailAddress = txtEmail.Text;
                po.Description = txtDescription.Text;
                po.Quantity = System.Int32.Parse(txtQuantity.Text);
    
                //A Blocking service call executed on secondary thread
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    strPOID = client.SubmitPO(po);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strMessage = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.SubmitOrderCallBack);
                this.BeginInvoke(CallbackHandler, strPOID, strMessage);
    
            }
    
            private void SubmitOrderCallBack(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                btnUpdate.Enabled = true;
                btnCancel.Enabled = true;
    
                txtOrderNumber.Text = strPOID;
                txtStatus.Text = strMessage;
            }
            #endregion
    
            #region Update button
            private void btnUpdate_Click(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                UpdateOrderHandler = new UpdateOrderDelegate(this.UpdateOrder);
                UpdateOrderHandler.BeginInvoke(null, null);
    
            }
    
            private void UpdateOrder()
            {
                string strMessage = "Your order update request has been received.";
                string strPOID = "";
    
                OrderWorkflowService.PurchaseOrder po = new OrderWorkflowService.PurchaseOrder();
                po.POID = txtOrderNumber.Text;
                po.EmailAddress = txtEmail.Text;
                po.Description = txtDescription.Text;
                po.Quantity = System.Int32.Parse(txtQuantity.Text);
    
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    strMessage = client.SubmitUpdate(po);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strMessage = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.UpdateOrderCallback);
                this.BeginInvoke(CallbackHandler, strPOID, strMessage);
    
            }
    
            private void UpdateOrderCallback(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                btnUpdate.Enabled = true;
                btnCancel.Enabled = true;
    
                txtStatus.Text = strMessage;
            }
            #endregion
    
            #region Cancel button
            private void btnCancel_Click(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                CancelOrderHandler = new CancelOrderDelegate(this.CancelOrder);
                CancelOrderHandler.BeginInvoke(null, null);
            }
    
            private void CancelOrder()
            {
                string strInOut = txtOrderNumber.Text;
    
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    client.SubmitCancellation(ref strInOut);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strInOut = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.CancelOrderCallback);
                this.BeginInvoke(CallbackHandler, txtOrderNumber.Text, strInOut);
            }
    
            private void CancelOrderCallback(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                //btnUpdate.Enabled = true;
                //btnCancel.Enabled = true;
    
                txtStatus.Text = strMessage;
            }
            #endregion
        }
    }
    

Procedimiento para compilar el cliente de pedidos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderClient y seleccione Volver a generar. Asegúrese de que el proyecto se compile correctamente en la ventana Resultados.

Prueba del servicio de pedidos

Procedimiento para probar el servicio de pedidos

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en OrderClient y seleccione Establecer como proyecto de inicio.

  2. En Visual Studio, haga clic en el menú Depurar y, a continuación, en Iniciar depuración. Se abrirá un Windows Form.

  3. En el formulario, haga clic en Enviar.

  4. Abra el Explorador de Windows y desplácese a la carpeta C:\DublinTutorial\Inbox.

  5. Espere hasta que aparezcan las tres notificaciones de correo electrónico. Pueden tardar entre tres y cuatro minutos.

Empaquetado del servicio de pedidos

Procedimiento para empaquetar el servicio WCF OrderProcessingService

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderProcessingService y seleccione Configuración de publicación/paquete.

  2. Especifique los valores siguientes:

    Propiedad Valor

    Crear paquete web como archivo ZIP

    (seleccionado)

    Ubicación donde se creará el paquete

    C:\DublinTutorial\DeploymentPackages\OrderProcessingService.zip

    Nombre de aplicación/sitio web de IIS que se usará en el servidor de destino

    OrderService/OrderProcessingService

  3. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto OrderProcessingService y seleccione Crear paquete.

  4. Repita el último procedimiento para crear paquetes para los otros tres proyectos con la siguiente configuración:

    Nombre del proyecto Ubicación donde se creará el paquete Nombre de aplicación/sitio web de IIS que se usará en el servidor de destino

    OrderWorkflowService

    C:\DublinTutorial\DeploymentPackages\OrderWorkflowService.zip

    OrderService/OrderWorkflowService

    ShippingService

    C:\DublinTutorial\DeploymentPackages\ShippingService.zip

    OrderService/ShippingService

    Nota

    Considere la actualización de las direcciones de los extremos de los servicios dependientes en los archivos Web.config para que reflejen el servidor en que se implementarán los paquetes antes de empaquetar un servicio.

Vea también

Conceptos

Tutorial sobre el uso de la interfaz de Windows Server AppFabric
Tutorial sobre el uso de Windows PowerShell

  2011-12-05