Vorgehensweise: Hosten eines Nicht-Dienstworkflows in IISHow to: Host a non-service workflow in IIS

Workflows, die keine Workflowdienste darstellen, können unter IIS/WAS gehostet werden.Workflows that are not workflow services can be hosted under IIS/WAS. Dies ist hilfreich, wenn ein Workflow gehostet werden muss, der von einem anderen Benutzer geschrieben wurde.This is useful when you need to host a workflow written by somebody else. Beispiel: Der Workflow-Designer wird erneut gehostet, und Benutzer können eigene Workflows erstellen.For example, if you rehost the workflow designer and allow users to create their own workflows. Durch das Hosten eines Workflows in IIS, bei dem es sich nicht um einen Dienstworkflow handelt, wird Unterstützung für Funktionen wie die Prozesswiederverwendung, das Herunterfahren der Anwendung und ihrer Dienste bei Leerlauf, die Prozessüberwachung und die meldungsbasierte Aktivierung bereitgestellt.Hosting non-service workflows in IIS provides support for features like process recycling, idle shutdown, process health monitoring, and message-based activation. Workflowdienste, die in IIS gehostet werden, enthalten Receive-Aktivitäten und werden beim Empfang einer Meldung durch IIS aktiviert.Workflow services hosted in IIS contain Receive activities and are activated when a message is received by IIS. Workflows, die keine Dienstworkflows sind, enthalten keine Messagingaktivitäten und können standardmäßig nicht durch Senden einer Meldung aktiviert werden.Non-service workflows do not contain messaging activities, and by default cannot be activated by sending a message. Um eine Instanz des Workflows zu erstellen, müssen Sie eine Klasse von WorkflowHostingEndpoint ableiten und einen Dienstvertrag mit Vorgängen erstellen.You must derive a class from WorkflowHostingEndpoint and define a service contract that contains operations to create an instance of the workflow. Dieses Thema führt Sie durch das Erstellen eines einfachen Workflows, definieren einen Dienstvertrag, ein Client verwenden kann, um den Workflow zu aktivieren, und Ableiten einer Klasse von WorkflowHostingEndpoint verwendet den Dienstvertrag für Workflow Erstellen von Anforderungen zu lauschen.This topic will walk you through creating a simple workflow, defining a service contract a client can use to activate the workflow, and deriving a class from WorkflowHostingEndpoint which uses the service contract to listen for workflow creating requests.

Erstellen eines einfachen WorkflowsCreate a simple workflow

  1. Erstellen Sie eine neue leere Visual Studio 2012Visual Studio 2012-Projektmappe mit dem Namen CreationEndpointTest.Create a new Visual Studio 2012Visual Studio 2012 empty solution called CreationEndpointTest.

  2. Fügen Sie der Projektmappe ein neues Projekt für eine WCF-Workflowdienstanwendung mit dem Namen SimpleWorkflow hinzu.Add a new WCF Workflow Service Application project called SimpleWorkflow to the solution. Der Workflow-Designer wird geöffnet.The workflow designer will open.

  3. Löschen Sie die ReceiveRequest-Aktivität und die SendResponse-Aktivität.Delete the ReceiveRequest and SendResponse activities. Durch diese Aktivitäten wird aus einem Workflow ein Workflowdienst.These activities are what makes a workflow a workflow service. Da im vorliegenden Fall nicht mit einem Workflowdienst gearbeitet wird, sind sie nicht länger erforderlich.Since we are not working with a workflow service, we no longer need them.

  4. Legen Sie den DisplayName für die Sequenzaktivität auf "Sequenzieller Workflow".Set the DisplayName for the sequence activity to "Sequential Workflow".

  5. Benennen Sie Service1.xamlx in Workflow1.xamlx um.Rename Service1.xamlx to Workflow1.xamlx.

  6. Klicken Sie auf den Designer außerhalb der Sequenzaktivität, und legen Sie die Eigenschaften "Name" und "ConfigurationName" auf "Workflow1"fest.Click the designer outside of the sequence activity, and set the Name and ConfigurationName properties to "Workflow1"

  7. Ziehen Sie eine WriteLine-Aktivität in die Sequence.Drag a WriteLine activity into the Sequence. Die WriteLine -Aktivität befindet sich der primitive Abschnitt der Toolbox.The WriteLine activity can be found in the Primitives section of the toolbox. Festlegen der Text Eigenschaft von der WriteLine Aktivität "Hello, World".Set the Text property of the WriteLine activity to "Hello, world".

    Der Workflow sollte jetzt wie das folgende Diagramm aussehen.The workflow should now look like the following diagram.

    Ein einfacher WorkflowA simple workflow

Erstellen des Dienstvertrags für die WorkflowerstellungCreate the workflow creation service contract

  1. Fügen Sie der Projektmappe Shared das neue Klassenbibliotheksprojekt CreationEndpointTest hinzu.Add a new class library project called Shared to the CreationEndpointTest solution.

  2. Fügen Sie dem Projekt Shared Verweise auf System.ServiceModel.dll, System.Configuration und System.ServiceModel.Activities hinzu.Add a reference to System.ServiceModel.dll, System.Configuration, and System.ServiceModel.Activities to the Shared project.

  3. Benennen Sie die Datei Class1.cs in IWorkflowCreation.cs um, und fügen Sie der Datei folgenden Code hinzu:Rename the Class1.cs file to IWorkflowCreation.cs and the following code to the file.

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.ServiceModel;  
    
    namespace Shared  
    {  
        //service contract exposed from the endpoint  
        [ServiceContract(Name = "IWorkflowCreation")]  
        public interface IWorkflowCreation  
        {  
            [OperationContract(Name = "Create")]  
            Guid Create(IDictionary<string, object> inputs);  
    
            [OperationContract(Name = "CreateWithInstanceId", IsOneWay = true)]  
            void CreateWithInstanceId(IDictionary<string, object> inputs, Guid instanceId);  
        }  
    }  
    

    Mit diesem Vertrag werden zwei Vorgänge definiert, mit denen jeweils eine neue Instanz des soeben erstellten Workflows erstellt wird, der kein Dienstworkflow ist.This contract defines two operations both create a new instance of the non-service workflow you just created. Während in dem einem Vorgang eine neue Instanz mit einer generierten Instanz-ID erstellt wird, können Sie die Instanz-ID für die neue Workflowinstanz in dem anderen Vorgang selbst angeben.One creates a new instance with a generated instance ID and the other allows you to specify the instance ID for the new workflow instance. Beide Methoden ermöglichen das Übergeben von Parametern an die neue Workflowinstanz.Both methods allow you to pass in parameters to the new workflow instance. Dieser Vertrag wird verfügbar gemacht werden, indem die WorkflowHostingEndpoint damit Clients neue Instanzen eines nicht-Workflows erstellen können.This contract will be exposed by the WorkflowHostingEndpoint to allow clients to create new instances of a non-service workflow.

Ableiten einer Klasse von WorkflowHostingEndpointDerive a class from WorkflowHostingEndpoint

  1. Fügen Sie eine neue Klasse namens CreationEndpoint abgeleitet WorkflowHostingEndpoint auf die Shared Projekt.Add a new class called CreationEndpoint derived from WorkflowHostingEndpoint to the Shared project.

    using System;  
    using System.Collections.Generic;  
    using System.Diagnostics;  
    using System.Globalization;  
    using System.ServiceModel;  
    using System.ServiceModel.Activities;  
    using System.ServiceModel.Channels;  
    
    namespace Shared  
    {  
        public class CreationEndpoint : WorkflowHostingEndpoint  
        {  
        }  
    }  
    
  2. Fügen Sie der Uri-Klasse die lokale statische defaultBaseUri-Variable mit dem Namen CreationEndpoint hinzu.Add a local static Uri variable called defaultBaseUri to the CreationEndpoint class.

    public class CreationEndpoint : WorkflowHostingEndpoint  
    {  
        static Uri defaultBaseUri;  
    }  
    
  3. Fügen Sie der CreationEndpoint-Klasse den folgenden Konstruktor hinzu.Add the following constructor to the CreationEndpoint class. Beachten Sie, dass der IWorkflowCreation-Dienstvertrag im Aufruf des Basiskonstruktors angegeben wird.Notice we specify the IWorkflowCreation service contract in the call to the base constructor.

    public CreationEndpoint(Binding binding, EndpointAddress address)  
       : base(typeof(IWorkflowCreation), binding, address)  
       {  
       }  
    
  4. Fügen Sie der CreationEndpoint-Klasse den folgenden Standardkonstruktor hinzu.Add the following default constructor to the CreationEndpoint class.

    public CreationEndpoint()  
       : this(GetDefaultBinding(),  
       new EndpointAddress(new Uri(DefaultBaseUri, new Uri(Guid.NewGuid().ToString(), UriKind.Relative))))  
       {  
       }  
    
  5. Fügen Sie der DefaultBaseUri-Klasse eine statische CreationEndpoint-Eigenschaft hinzu.Add a static DefaultBaseUri property to the CreationEndpoint class. Diese Eigenschaft enthält einen standardmäßigen Basis-URI, sofern keiner angegeben wurde.This property will be used to hold a default base URI if one is not provided.

    static Uri DefaultBaseUri  
    {  
       get  
       {  
          if (defaultBaseUri == null)  
          {  
             defaultBaseUri = new Uri(string.Format(CultureInfo.InvariantCulture, "net.pipe://localhost/workflowCreationEndpoint/{0}/{1}",  
                Process.GetCurrentProcess().Id,  
                AppDomain.CurrentDomain.Id));  
          }  
          return defaultBaseUri;  
       }  
     }  
    
  6. Erstellen Sie die folgende Methode, um die Standardbindung für den Erstellungsendpunkt abzurufen.Create the following method to get the default binding to use for the creation endpoint.

    //defaults to NetNamedPipeBinding  
    public static Binding GetDefaultBinding()  
    {  
       return new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { TransactionFlow = true };  
    }  
    
  7. Überschreiben Sie die OnGetInstanceId-Methode, um die Instanz-ID für den Workflow zurückzugeben.Override the OnGetInstanceId method to return the workflow instance ID. Wenn die Action Header endet mit "Create" eine leere GUID zurück, wenn die Action Header mit die GUID, die an die Methode übergebenen "CreateWithInstanceId" endet.If the Action header ends with "Create" return an empty GUID, if the Action header ends with "CreateWithInstanceId" return the GUID passed into the method. Andernfalls wird eine InvalidOperationException ausgelöst.Otherwise, throw an InvalidOperationException. Diese Action-Header entsprechen den beiden Vorgängen, die im IWorkflowCreation-Dienstvertrag definiert sind.These Action headers correspond to the two operations defined in the IWorkflowCreation service contract.

    protected override Guid OnGetInstanceId(object[] inputs, OperationContext operationContext)  
    {  
       //Create was called by client  
       if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))  
       {  
          return Guid.Empty;  
       }  
       //CreateWithInstanceId was called by client  
       else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId"))  
       {  
          return (Guid)inputs[1];  
       }  
       else  
       {  
          throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);  
       }  
    }  
    
  8. Überschreiben Sie die OnGetCreationContext-Methode, um einen WorkflowCreationContext zu erstellen. Fügen Sie Argumente für den Workflow hinzu, senden Sie die Instanz-ID an den Client, und geben Sie den WorkflowCreationContext zurück.Override the OnGetCreationContext method to create a WorkflowCreationContext and add any arguments for the workflow, send the instance ID to the client, and then return the WorkflowCreationContext.

    protected override WorkflowCreationContext OnGetCreationContext(object[] inputs, OperationContext operationContext, Guid instanceId, WorkflowHostingResponseContext responseContext)  
    {  
       WorkflowCreationContext creationContext = new WorkflowCreationContext();  
       if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create") || (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId")))  
       {  
          Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];  
          if (arguments != null && arguments.Count > 0)  
          {  
             foreach (KeyValuePair<string, object> pair in arguments)  
             {  
                //arguments to pass to the workflow  
                creationContext.WorkflowArguments.Add(pair.Key, pair.Value);  
             }  
          }  
          //reply to client with instanceId  
          responseContext.SendResponse(instanceId, null);  
       }  
       else  
       {  
          throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);  
       }  
       return creationContext;  
    }  
    

Erstellen eines Standardendpunktelements zum Konfigurieren des WorkflowCreationEndpointCreate a standard endpoint element to allow you to configure the WorkflowCreationEndpoint

  1. Fügen Sie dem Projekt CreationEndpoint einen Verweis auf Shared hinzu.Add a reference to Shared in the CreationEndpoint project

  2. Fügen Sie dem Projekt CreationEndpointElement die neue StandardEndpointElement-Klasse hinzu, die von CreationEndpoint abgeleitet wurde.Add a new class called CreationEndpointElement, derived from StandardEndpointElement to the CreationEndpoint project. Diese Klasse stellt einen CreationEndpoint in einer web.config-Datei dar.This class will represent a CreationEndpoint in a web.config file.

    using System;  
    using System.Configuration;  
    using System.ServiceModel.Activities;  
    using System.ServiceModel.Configuration;  
    using System.ServiceModel.Description;  
    using Shared;  
    
    namespace CreationEndpointTest  
    {  
        //config element for CreationEndpoint  
        public class CreationEndpointElement : StandardEndpointElement  
        {  
       }  
    
  3. Fügen Sie die EndpointType-Eigenschaft hinzu, um den Typ des Endpunkts zurückzugeben.Add a property called EndpointType to return the type of the endpoint.

    protected override Type EndpointType  
    {  
       get { return typeof(CreationEndpoint); }  
    }  
    
  4. Überschreiben Sie die CreateServiceEndpoint-Methode, und geben Sie einen neuen CreationEndpoint zurück.Override the CreateServiceEndpoint method and return a new CreationEndpoint.

    protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription contractDescription)  
    {  
       return new CreationEndpoint();  
    }  
    
  5. Überladen Sie die folgenden Methoden: OnApplyConfiguration, OnApplyConfiguration, OnInitializeAndValidate und OnInitializeAndValidate.Overload the OnApplyConfiguration, OnApplyConfiguration, OnInitializeAndValidate, and OnInitializeAndValidate methods. Diese Methoden müssen lediglich definiert werden; es ist nicht erforderlich, Code hinzuzufügen.These methods just need to be defined, you do not need to add any code to them.

    protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ChannelEndpointElement channelEndpointElement)  
    {  
    }  
    
    protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ServiceEndpointElement serviceEndpointElement)  
    {  
    }  
    
    protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement)  
    {  
    }  
    
    protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement)  
    {  
    }  
    
  6. Fügen Sie der Datei CreationEndpointElement.cs im Projekt CreationEndpoint die Auflistungsklasse für CreationEndpoint hinzu.Add the collection class for CreationEndpoint to the CreationEndpointElement.cs file in the CreationEndpoint project. Diese Klasse wird von der Konfiguration für eine Reihe von CreationEndpoint-Instanzen in einer web.config-Datei verwendet.This class is used by configuration to hold a number of CreationEndpoint instances in a web.config file.

    public class CreationEndpointCollection : StandardEndpointCollectionElement<CreationEndpoint, CreationEndpointElement>  
    {  
    }  
    
  7. Erstellen Sie die Projektmappe.Build the solution.

Hosten des Workflows in IISHost the workflow in IIS

  1. Erstellen Sie in IIS die neue Anwendung MyCreationEndpoint.Create a new application called MyCreationEndpoint in IIS.

  2. Kopieren Sie die Datei workflow1.xaml, die vom Workflow-Designer generiert wurde, in das Anwendungsverzeichnis, und benennen Sie sie in workflow1.xamlx um.Copy the workflow1.xaml file generated by the workflow designer to the application directory and rename it to workflow1.xamlx.

  3. Kopieren Sie die Datei shared.dll und die Datei CreationEndpoint.dll in das BIN-Verzeichnis der Anwendung (ggf. müssen Sie das Verzeichnis zunächst erstellen).Copy the shared.dll and CreationEndpoint.dll files to the application’s bin directory (create the bin directory if it is not present).

  4. Ersetzen Sie den Inhalt der web.config-Datei im Projekt CreationEndpoint durch folgenden Code.Replace the contents of the Web.config file in the CreationEndpoint project with the following code.

    <?xml version="1.0" encoding="utf-8" ?>  
    <configuration>  
      <system.web>  
        <compilation debug="true" targetFramework="4.0" />  
      </system.web>   
    </configuration>  
    
  5. Registrieren Sie den <system.web> nach dem CreationEndpoint-Element durch Hinzufügen des folgenden Konfigurationscodes.After the <system.web> element, register CreationEndpoint by adding the following configuration code.

    <system.serviceModel>  
        <!--register CreationEndpoint-->  
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />  
        <extensions>  
          <endpointExtensions>  
            <add name="creationEndpoint" type="CreationEndpointTest.CreationEndpointCollection, CreationEndpoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />  
          </endpointExtensions>  
        </extensions>  
    </system.serviceModel>  
    

    Dadurch wird die CreationEndpointCollection-Klasse registriert, und Sie können einen CreationEndpoint in einer web.config-Datei konfigurieren.This registers the CreationEndpointCollection class so you can configure a CreationEndpoint in a web.config file.

  6. Hinzufügen einer <service> Element (nach der </extensions > Tag) mit einem CreationEndpoint , um eingehende Nachrichten zu lauschen.Add a <service> element (after the </extensions> tag) with a CreationEndpoint which will listen for incoming messages.

    <services>  
          <!-- add endpoint to service-->  
          <service name="Workflow1" behaviorConfiguration="basicConfig" >  
            <endpoint kind="creationEndpoint" binding="basicHttpBinding" address=""/>  
          </service>  
        </services>  
    
  7. Hinzufügen einer <Verhalten > Element (nach der < /services > Tag) um Dienstmetadaten zu aktivieren.Add a <behaviors> element (after the </services> tag) to enable service metadata.

    <behaviors>  
          <serviceBehaviors>  
            <behavior name="basicConfig">  
              <serviceMetadata httpGetEnabled="true" />  
            </behavior>  
          </serviceBehaviors>  
        </behaviors>  
    
  8. Kopieren Sie die web.config-Datei in Ihr IIS-Anwendungsverzeichnis.Copy the web.config to your IIS application directory.

  9. Überprüfen Sie die Funktion des Erstellungsendpunkts, indem Sie Internet Explorer starten und zu http://localhost/MyCreationEndpoint/Workflow1.xamlx navigieren.Test to see if the creation endpoint is working by starting Internet Explorer and browsing to http://localhost/MyCreationEndpoint/Workflow1.xamlx. Internet Explorer sollte nun folgenden Bildschirm anzeigen:Internet Explorer should display the following screen:

    Testen des DienstsTesting the service

Erstellen Sie einen Client, mit dem der CreationEndpoint aufgerufen wird.Create a client that will call the CreationEndpoint.

  1. Fügen Sie der Projektmappe CreationEndpointTest eine neue Konsolenanwendung hinzu.Add a new Console application to the CreationEndpointTest solution.

  2. Fügen Sie Verweise auf System.ServiceModel.dll und System.ServiceModel.Activities sowie das Projekt Shared hinzu.Add references to System.ServiceModel.dll, System.ServiceModel.Activities, and the Shared project.

  3. In der Main Methode erstellt eine ChannelFactory<TChannel> des Typs IWorkflowCreation , und rufen Sie CreateChannel.In the Main method create a ChannelFactory<TChannel> of type IWorkflowCreation and call CreateChannel. Dadurch wird ein Proxy zurückgegeben.This will return a proxy. Anschließend können Sie Create für den Proxy aufrufen, um die Workflowinstanz zu erstellen, die unter IIS gehostet wird:You can then call Create on that proxy to create the workflow instance hosted under IIS:

    using System.Text;  
    using Shared;  
    using System.ServiceModel;  
    
    namespace CreationEndpointClient  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                try  
                {  
                    //client using BasicHttpBinding  
                    IWorkflowCreation client = new ChannelFactory<IWorkflowCreation>(new BasicHttpBinding(), new EndpointAddress("http://localhost/CreationEndpoint/Workflow1.xamlx")).CreateChannel();  
    
                    Console.WriteLine("Workflow Instance created using CreationEndpoint added in config. Instance Id: {0}", client.Create(null));  
                    Console.WriteLine("Press return to exit ...");  
                    Console.ReadLine();  
                }  
                catch (Exception ex)  
                {  
                    Console.WriteLine(ex);  
                    Console.ReadLine();  
                }  
            }  
        }  
    }  
    
  4. Führen Sie den CreationEndpointClient aus.Run the CreationEndpointClient. Die Ausgabe sollte wie folgt aussehen:The output should look like the following:

    Workflow Instance created using CreationEndpoint added in config. Instance Id: 0875dac0-2b8b-473e-b3cc-abcb235e9693Press return to exit ...  
    

    Hinweis

    Die Ausgabe des Workflows wird nicht angezeigt, da IIS nicht über eine Konsolenausgabe verfügt.You will not see the output of the workflow because it is running under IIS which has no console output.

BeispielExample

Nachfolgend ist der vollständige Code für dieses Beispiel angegeben.The following is the complete code for this sample.

<!-— workflow1.xamlx -->  
<WorkflowService mc:Ignorable="sap"   
                 ConfigurationName="Workflow1"   
                 sap:VirtualizedContainerService.HintSize="263,230"   
                 Name="Workflow1"   
                 mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"   
                 xmlns="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel"   
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
                 xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System"   
                 xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"   
                 xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/activities"   
                 xmlns:s="clr-namespace:System;assembly=mscorlib"   
                 xmlns:s1="clr-namespace:System;assembly=System"   
                 xmlns:s2="clr-namespace:System;assembly=System.Xml"   
                 xmlns:s3="clr-namespace:System;assembly=System.Core"   
                 xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities"   
                 xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"   
                 xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System"   
                 xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel"   
                 xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core"   
                 xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib"   
                 xmlns:sd="clr-namespace:System.Data;assembly=System.Data"   
                 xmlns:sl="clr-namespace:System.Linq;assembly=System.Core"   
                 xmlns:st="clr-namespace:System.Text;assembly=mscorlib"   
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
  <p:Sequence DisplayName="Sequential Service"   
              sad:XamlDebuggerXmlReader.FileName="c:\projects\CreationEndpointTest\CreationEndpoint\Service1.xamlx"   
              sap:VirtualizedContainerService.HintSize="233,200"   
              mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">  
    <p:Sequence.Variables>  
      <p:Variable x:TypeArguments="CorrelationHandle" Name="handle" />  
      <p:Variable x:TypeArguments="x:Int32" Name="data" />  
    </p:Sequence.Variables>  
    <sap:WorkflowViewStateService.ViewState>  
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">  
        <x:Boolean x:Key="IsExpanded">True</x:Boolean>  
      </scg3:Dictionary>  
    </sap:WorkflowViewStateService.ViewState>  
    <p:WriteLine sap:VirtualizedContainerService.HintSize="211,61" Text="Hello, world" />  
  </p:Sequence>  
</WorkflowService>  
// CreationEndpointElement.cs  
using System;  
using System.Configuration;  
using System.ServiceModel.Activities;  
using System.ServiceModel.Configuration;  
using System.ServiceModel.Description;  
using Shared;  

namespace CreationEndpointTest  
{  
    //config element for CreationEndpoint  
    public class CreationEndpointElement : StandardEndpointElement  
    {  
        protected override Type EndpointType  
        {  
            get { return typeof(CreationEndpoint); }  
        }  

        protected override ConfigurationPropertyCollection Properties  
        {  
            get  
            {  
                ConfigurationPropertyCollection properties = base.Properties;  
                properties.Add(new ConfigurationProperty("name", typeof(String), null, ConfigurationPropertyOptions.IsRequired));  
                return properties;  
            }  
        }  

        protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription contractDescription)  
        {  
            return new CreationEndpoint();  
        }  

        protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ChannelEndpointElement channelEndpointElement)  
        {  
        }  

        protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ServiceEndpointElement serviceEndpointElement)  
        {  
        }  

        protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement)  
        {  
        }  

        protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement)  
        {  
        }  
    }  

    public class CreationEndpointCollection : StandardEndpointCollectionElement<CreationEndpoint, CreationEndpointElement>  
    {  
    }  
}  
<!-- web.config -->  
<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
  <system.web>  
    <compilation debug="true" targetFramework="4.0" />  
  </system.web>  
  <system.serviceModel>  
    <!--register CreationEndpoint-->  
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />  
    <extensions>  
      <endpointExtensions>  
        <add name="creationEndpoint" type="CreationEndpointTest.CreationEndpointCollection, Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />  
      </endpointExtensions>  
    </extensions>  
    <services>  
      <!-- add endpoint to service-->  
      <service name="Workflow1" behaviorConfiguration="basicConfig" >  
        <endpoint kind="creationEndpoint" binding="basicHttpBinding" address=""/>  
      </service>  
    </services>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="basicConfig">  
          <serviceMetadata httpGetEnabled="true" />  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
  </system.serviceModel>  
</configuration>  
// IWorkflowCreation.cs  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.ServiceModel;  

namespace Shared  
{  
    //service contract exposed from the endpoint  
    [ServiceContract(Name = "IWorkflowCreation")]  
    public interface IWorkflowCreation  
    {  
        [OperationContract(Name = "Create")]  
        Guid Create(IDictionary<string, object> inputs);  

        [OperationContract(Name = "CreateWithInstanceId", IsOneWay = true)]  
        void CreateWithInstanceId(IDictionary<string, object> inputs, Guid instanceId);  
    }  
}  
// CreationEndpoint.cs  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.ServiceModel.Activities;  
using System.ServiceModel.Channels;  
using System.ServiceModel;  
using System.Globalization;  
using System.Diagnostics;  

namespace Shared  
{  
    public class CreationEndpoint : WorkflowHostingEndpoint  
    {  
        static Uri defaultBaseUri;  

        public CreationEndpoint(Binding binding, EndpointAddress address)  
            : base(typeof(IWorkflowCreation), binding, address) { }  

        public CreationEndpoint()  
            : this(GetDefaultBinding(),  
                new EndpointAddress(new Uri(DefaultBaseUri, new Uri(Guid.NewGuid().ToString(), UriKind.Relative)))) { }  

        static Uri DefaultBaseUri  
        {  
            get  
            {  
                if (defaultBaseUri == null)  
                {  
                    defaultBaseUri = new Uri(string.Format(CultureInfo.InvariantCulture, "net.pipe://localhost/workflowCreationEndpoint/{0}/{1}",  
                        Process.GetCurrentProcess().Id,  
                        AppDomain.CurrentDomain.Id));  
                }  
                return defaultBaseUri;  
            }  
        }  

        //defaults to NetNamedPipeBinding  
        public static Binding GetDefaultBinding()  
        {  
            return new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { TransactionFlow = true };  
        }  

        protected override Guid OnGetInstanceId(object[] inputs, OperationContext operationContext)  
        {  
            //Create was called by client  
            if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))  
            {  
                return Guid.Empty;  
            }  

            //CreateWithInstanceId was called by client  
            else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId"))  
            {  
                return (Guid)inputs[1];  
            }  
            else  
            {  
                throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);  
            }  
        }  

        protected override WorkflowCreationContext OnGetCreationContext(object[] inputs, OperationContext operationContext, Guid instanceId, WorkflowHostingResponseContext responseContext)  
        {  
            WorkflowCreationContext creationContext = new WorkflowCreationContext();  
            if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))  
            {  
                Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];  
                if (arguments != null && arguments.Count > 0)  
                {  
                    foreach (KeyValuePair<string, object> pair in arguments)  
                    {  
                        //arguments to pass to the workflow  
                        creationContext.WorkflowArguments.Add(pair.Key, pair.Value);  
                    }  
                }  
                //reply to client with instanceId  
                responseContext.SendResponse(instanceId, null);  
            }  
            else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId"))  
            {  
                Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];  
                if (arguments != null && arguments.Count > 0)  
                {  
                    foreach (KeyValuePair<string, object> pair in arguments)  
                    {  
                        //arguments to pass to workflow  
                        creationContext.WorkflowArguments.Add(pair.Key, pair.Value);  
                    }  
                }  
            }  
            else  
            {  
                throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);  
            }  
            return creationContext;  
        }  
    }  
}  
// CreationEndpointClient.cs  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using Shared;  
using System.ServiceModel;  

namespace CreationClient  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            try  
            {  
                //client using BasicHttpBinding  
                IWorkflowCreation client = new ChannelFactory<IWorkflowCreation>(new BasicHttpBinding(), new EndpointAddress("http://localhost/MyCreationEndpoint/Workflow1.xamlx")).CreateChannel();  

                Console.WriteLine("Workflow Instance created using CreationEndpoint added in config. Instance Id: {0}", client.Create(null));  
                Console.WriteLine("Press return to exit ...");  
                Console.ReadLine();  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine(ex);  
                Console.ReadLine();  
            }  

        }  
    }  

}  

Möglicherweise erscheint dieses Beispiel verwirrend, da zu keiner Zeit ein Dienst implementiert wird, der IWorkflowCreation implementiert.This example may seem confusing because you never implement a service that implements IWorkflowCreation. Diese Aufgabe wird von CreationEndpoint übernommen.This is because the CreationEndpoint does this for you.

Siehe auchSee Also

WorkflowdiensteWorkflow Services
Hosten in IIS (Internetinformationsdienste)Hosting in Internet Information Services
Bewährte Methoden für das Hosten in IIS (Internetinformationsdienste)Internet Information Services Hosting Best Practices
Hostinganweisungen des InternetinformationsdienstsInternet Information Service Hosting Instructions
Architektur von Windows-WorkflowsWindows Workflow Architecture
WorkflowHostingEndpoint: LesezeichenwiederaufnahmeWorkflowHostingEndpoint Resume Bookmark
Erneutes Hosten des Workflow-DesignersRehosting the Workflow Designer
Übersicht über Windows-WorkflowWindows Workflow Overview