serge's profileSerge Luca (Sharepoint M...PhotosBlogLists Tools Help

Blog


    January 23

    Hosting a WCF Serviced Workflow in IIS 7 and using the persistence service (Visual Studio 2008)

     

     

    By Serge Luca

    MVP Windows Workflow Foundation

    In the previous post I showed you how to host a "WCF serviced" workflow and how to use a persistence  service in a console application.

    Now, let's move our workflow service to IIS7. Code can be downloaded here.

    1.Download the code of the previous post.

    2.In IIS7 Admin Manager, create a virtual directory that will point to the WFServiceLibrary folder, assign a port number (for instance 8082). Make sure the service dll is in the .bin folder just below the virtual root.

    sshot-185

    3.In the virtual root, add a .svc file (myservice.svc)  with the following code:

    <%@ServiceHost language=c# Debug="true" Service="WFServiceLibrary.Workflow1" Factory="System.ServiceModel.Activation.WorkflowServiceHostFactory" %>

    4.Add a web.config file and configure it like this:

    <configuration>
      <system.web>
        <compilation debug="true" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="WFServiceLibrary.Workflow1" behaviorConfiguration="WFServiceLibrary.Workflow1Behavior">
            <host>
              <baseAddresses>
                <add baseAddress="/" />
              </baseAddresses>
            </host>
            <endpoint address=""
                      binding="wsHttpContextBinding"
                      contract="WFServiceLibrary.IWorkflow1">
              <!--
                  Upon deployment, the following identity element should be removed or replaced to reflect the
                  identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity
                  automatically.
              -->
              <identity>
                <dns value="localhost"/>
              </identity>
            </endpoint>
            <endpoint address="mex"
                      binding="mexHttpBinding"
                      contract="IMetadataExchange" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="WFServiceLibrary.Workflow1Behavior"  >
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
              <serviceCredentials>
                <windowsAuthentication
                    allowAnonymousLogons="false"
                    includeWindowsGroups="true" />
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>

    5.Now test the svc file in the browser to verify that you can grab the metadata (wsd):

    you should get this:

     

    image

     

    6.Add a console application project (name it IISClient) in order to invoke the service:

    7.In the IISClient project add a service reference to the WCF service:

    image

    Keep the default name and click on ok. A proxy will be generated.

    8.Add a reference to the System.WorkflowService assembly in the IISclient project .

    9.Implement the client-side code :

    static void Main(string[] args)

    {

    ServiceReference1.

    Workflow1Client proxy= new ServiceReference1.Workflow1Client("WSHttpContextBinding_IWorkflow1");

    // much faster to provide the endpoint directly, I don't know why
    // new ServiceReference1.Workflow1Client(new WSHttpContextBinding(),
    // new EndpointAddress("http://localhost:8082/myservice.svc"));

    Console.WriteLine(proxy.GetData(0));

    }

     

    10.Run the code

     image

    Ok that works !

    11.Let's modify the web.config file to register the persistence service:

    add workflowRuntime setting in the default behavior:

    image

    Here is the workflowRuntime setting:

    <

    workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true">

    <

    services>

    <

    add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"connectionString="Data Source=localhost\sqlexpress;Initial Catalog=PersistenceDB2;Integrated Security=True;Pooling=False"LoadIntervalSeconds="1" UnLoadOnIdle= "true" />

    </

    services>

    </

    workflowRuntime>

    Make sure the persistence database (PersistenceDB2 here has been created, see my previous post for more infos)

    12 (optional)If you want to access the WorkflowRuntime by code even if your service is hosted in IIS (and by the way an .svc file), then your need to create your own WorkflowServiceHost factory by creating a class derived from System.ServiceModel.Activation.WorkflowServiceHostFactory and by overriding its CreateServiceHost method.

     

    • In the WFServiceLibrary project  add a new class called MyCustomServiceHost derived from WorkflowServiceHostFactory (in our case we will register the persistence service in the WorkflowRuntime) :

    public class MyCustomServiceHost : WorkflowServiceHostFactory

    {

    public override ServiceHostBase CreateServiceHost(string constructorString,Uri[] baseAddresses){

    WorkflowServiceHost serviceHost=
    (
    WorkflowServiceHost)base.CreateServiceHost(constructorString, baseAddresses);
    WorkflowRuntime wRuntime =serviceHost.Description.Behaviors.Find<WorkflowRuntimeBehavior>().WorkflowRuntime;

    string connectionString=@"Data Source=localhost\sqlexpress;Initial Catalog=PersistenceDB2;Integrated Security=True;Pooling=False";

    wRuntime.AddService(

    new SqlWorkflowPersistenceService(connectionString,true,new TimeSpan(1,0,0), new TimeSpan(0,0,1)));

    return serviceHost;

    }

    }

    • Modify the .svc file to use our new factory class:

    <%

    @ServiceHost language=c# Debug="true" Service="WFServiceLibrary.Workflow1" Factory="WFServiceLibrary.MyCustomServiceHost" %>
    • Remove the Persistence service definition in the web.config file.

    This hands-on training is the property of U2U and may not be organized in class or in group without the prior written permission of U2U. Should you wish to organize this hands-on training in your company or institution, please contact U2U first to enter into a licence agreement. Each trainer or teacher using this hands-on training should have a licence agreement. Please ask your trainer or U2U whether he or she has entered into a licence agreement with U2U.

    The hyperlink "www.u2u.be/msdna" to this hands-on training may be placed on your website for free, on the condition that the name and the logo of U2U are clearly mentioned in the reference. Please send us a mail containing the link to the web page our reference is used on.

     

     

     

     

     

    January 15

    Using the persistence service in a WCF 3.5 hosted workflow

     

    Using the persistence service in a WCF 3.5 hosted workflow   

     

    By Serge Luca

    MVP Windows Workflow Foundation

    This morning a  colleague at U2U asked me how to use the persistence service in a workflow hosted in WCF (.Net 3.5 and Visual Studio 2008).

    I've created  a quick (and dirty, sorry) step by step tutorial on how to achieve it.

    Click here to download the code.

    1.Start Visual Studio 2008 and create a new Sequential Workflow Service Library project ; call it WFServiceLibrary.

    sshot-185

    A workflow with a WF-WCF 3.5 Receive activity linked to the GetData method of a IWorkflow interface will be generated:

    sshot-186

    sshot-187

    sshot-188

     

    2.Drag and drop a code activity into the Receive activity and set the ReturnValue to a funny string

    sshot-190

    sshot-189

    3.Create a WCF host for the workflow by generating a Console project

    sshot-191

    ...and add the following references:

    sshot-192

     

    And don't forget to add a reference to the WFServiceLibrary as well...

    4.In the Host project,..host the workflow and don't forget to create the persistence database with the scripts provided with the .Net framework :

    sshot-193

    The second parameter of the persistence service (unloadOnIdle) is set to true, which means the workflow will be persisted by the workflow runtime when it is idle; add a delay activity after the Receive activity to make it idle:

    sshot-194

    Set its timeout duration to 30 secs.

    5.Let's create the client application by adding a Console application to the solution:

    sshot-195

    Don't forget to reference the following .Net assemblies and the library project (just to get the interface definition: I told you it was quick and dirty)

    sshot-201

    Implement the client-side code in the Main() function :

    sshot-196

    6.Start the Host (if your run it Vista, I strongly suggest that you start it with admin privileges):

    sshot-198

    7.Start the client:

    sshot-199

    Ok, the communication works...

    8.Check the persistence database (InstanceState table):

    sshot-200

    yes the workflow is persisted!!! After 30 seconds, it will be removed from the database.

    Click here to download the code.


    This hands-on training is the property of U2U and may not be organized in class or in group without the prior written permission of U2U. Should you wish to organize this hands-on training in your company or institution, please contact U2U first to enter into a licence agreement. Each trainer or teacher using this hands-on training should have a licence agreement. Please ask your trainer or U2U whether he or she has entered into a licence agreement with U2U.

    The hyperlink "www.u2u.be/msdna" to this hands-on training may be placed on your website for free, on the condition that the name and the logo of U2U are clearly mentioned in the reference. Please send us a mail containing the link to the web page our reference is used on.