Welcome to Windows Workflow Foundation (WF)
Top Tasks :

WF Community Bloggers

Browse by Tags

All Tags » WCF   (RSS)

  • Code from my webcast earlier today

    I did a webcast on using WCF from Silverlight 2.0 this morning - I think you can see the replay here in about 24-hours - http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032380766&EventCategory=5&culture=en-US&CountryCode=US If you watched (or watch the replay) here is the code: webcastcode.zip (3.46 MB) Check out my BizTalk R2 Training . Read More...
  • Multi-named web sites and WCF

    Glav posts about a problem I've also had recently - that Matt helped me figure out how to solve. The exception is (repeated here for seach purposes): This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. Parameter name: item Description : An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.ArgumentException: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. Parameter name : item The way to solve this problem is to setup multiple web sites in IIS (rather than having one site that has multiple Host entries) - and point all the websites to the same directory. Hope this helps someone. Check out my BizTalk R2 Training . Read More...
  • How to Download all of Visual Studio 2008 SP1

     VS2008 SP1 Beta is quite a package. By default the installation downloads the packages as needed and when needed. Now that is just fine if you only need to install a single machine. But when you need to install multiple, possibly virtual, machines like I have to it just wastes a lot of bandwidth and time Sad. Fortunately there is a solution and it can be found here in the blog post by Heath Stewart.

    Enjoy! 

  • Project Mole or visual studio visualizers on steroids

    Visual Studio visualizers are pretty cool and can help you quite a bit when debugging but you need to develop them and that just ads to the workload. So how about having someone else do it? Well Microsoft added a few visualizers to VS2008 and VS2008 but they are pretty much limited to text, html and XML data.

     

    Luckily some people liked the idea of using visualizers and actually decided to take it to the next level with project Mole.

    Its a really great viewer to inspect your data and the "Black Ops" feature that allows you to inspect all private members is awesome.

    One quick tip: If you want to use the Mole with any variable use the "new WeakReference(variable)" in the watch window trick!

     

    Enjoy!

    www.TheProblemSolver.nl
    http://wiki.WindowsWorkflowFoundation.eu

  • On the WF ReceiveActivity and WCF bindings

    The new ReceiveActivity and SendActivity that marry Windows Workflow Foundation (WF) and Windows Communication Foundation (WCF) are really cool Smile. Getting started is easy because a new Sequential Workflow Service Library, found under WCF instead of Workflow in VS2008, uses nice defaults for everything. But sooner or later you need to change these defaults and you need to know what can be done and what can't.

    When you want to use the new ReceiveActivity in a workflow you need to use a compatible WCF binding. The reason for this requirement is that the conversation context, see this blog post, is part of the message and needs to be retrieved and returned. The following code returns a list of all WCF binding and how they are composed:

    Sub Main()

    Dim assemblies As New List(Of Assembly)()

    ' .NET 3.0

    assemblies.Add(GetType(ServiceHost).Assembly)

    ' .NET 3.5

    assemblies.Add(GetType(WorkflowServiceHost).Assembly)

    assemblies.Add(GetType(WebServiceHost).Assembly)

     

    Dim query = From assembly In assemblies _

    From type In assembly.GetTypes() _

    Where type.IsSubclassOf(GetType(Binding)) _

    AndAlso Not type.IsAbstract _

    AndAlso type.IsPublic _

    Order By type.Name _

    Select type

     

    PrintBinding(query.ToList)

     

    Console.ReadLine()

    End Sub

     

    Private Sub PrintBinding(ByVal types As List(Of Type))

    For Each type In types

    Console.WriteLine(type.FullName)

    Try

    Dim binding As Binding = _

    CType(Activator.CreateInstance(type), Binding)

    Dim elements = binding.CreateBindingElements

    For Each element In elements

    Console.WriteLine(vbTab + element.GetType().FullName)

    Next

    Catch ex As Exception

    Console.WriteLine(ex.Message)

    End Try

    Console.WriteLine()

    Next

    End Sub

     

    The classes responsible for inserting and removing these conversation tokens are ContextRequestChannel and ContextReplyChannel and they are instantiated by the ContextBindingElement. So seems we are restricted to using BasicHttpContextBinding, NetTcpContextBinding or WSHttpContextBinding.

    So it seems we cannot use NetMsmqBinding which is a shame because one way reliable messaging is the perfect fit for workflow as far as I am concerned. Well not quite so fast because we still have the CustomBinding where we can configure the stack just the way we want right?

    Yeah we do but there is a problem Sad. It turns out the ContextBinding requires a channel with an IReplyChannel interface and the NetMsmqBinding actually implement an IInputChannel or an IOutputChannel. Which one actually depends if you are the client or the service.

    And thinking about how WF/WCF conversations works this restriction makes sense. After all a ReceiveActivity is called without a context in order to create a new workflow, assuming the CanCreateInstance property equals true, and returns the workflow instanceId in the context as part of the response. This design kind of rules out one-way messages and thereby NetMsmqBinding.

    Now this sucks big time if you ask me Sad. I would much rather have seen that you could specify the instanceId of the workflow to be created, just as you can with the WorkflowRuntime.CreateWorkflow() where a number of the overloads let you specify the workflows instanceId. I suppose it is possible to create a different context binding but that would be quite some work and, I assume, duplicate a lot of code already written my Microsoft. So let's hope they see the light and add MSMQ/ReceiveActivity intergration.

     

    Enjoy!

    www.TheProblemSolver.nl
    http://wiki.WindowsWorkflowFoundation.eu

  • ReceiveActivity, ContextTokens and conversations

    In a previous blog post I showed how to use the ReceiveActivity with long running workflow and how to extract the workflow instanceId from the context using the IContextManager. I also showed how to rebuild this context at a later date when you use a new proxy object to call the same workflow instance.

    But what happens when there are multiple ReceiveActivity instances waiting for the same request in a workflow. In the workflow below both indicated activities are in a parallel activity so they are waiting at the same time and for the same request.

    The way to keep them apart is by specifying the ContextToken for the two ReceiveActivity objects. The picture below shows the ReceiveActivity to the right, the one to the left has a ContextToken named LeftBranch.

    Now we know how to keep them apart in the workflow we still need a way to specify this at the clients end. This is done using a conversationId setting on the same context as we specified the instanceId. The only problem here is that this conversationId is a Guid and not something the client can determine by itself so the workflow needs to supply it somehow. For this example I just kept things simple and returned the conversationId from the first ReceiveActivity call. This is the code in the CodeActivity that does just that:

    private void codeActivity1_ExecuteCode(object sender, EventArgs e)

    {

    IDictionary<string, string> context = RightReceiveActivity.Context;

     

    string temp;

     

    if (context.TryGetValue("conversationId", out temp))

    ReturnValue = temp;

    }

     

    All I need to do is het the Context from the ReceiveActivity I am interested in, the right one in this case, and retrieve the conversationId from it. Remember the context is an IDictionary<string, string> and it will also contain the instanceId for the workflow. In fact I could have just returned this context to the client for future use but as I was using the simple standard interface generated and the client already knew the workflow instanceId I decided to skip this step.

    The client code to set the conversationId is simple:

    Workflow1Client proxy = new Workflow1Client();

     

    IContextManager contextManager = proxy.InnerChannel.GetProperty<IContextManager>();

    if (!string.IsNullOrEmpty(_conversationId))

    _context.Add("conversationId", _conversationId);

     

    contextManager.SetContext(_context);

     

    DumpContext(proxy);

     

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

     

    Where the _context field points to the context used when creating the workflow and the conversationId is returned from the first GetData() call.

     

    Enjoy!

    www.TheProblemSolver.nl
    http://wiki.WindowsWorkflowFoundation.eu

  • Configuring a self hosted ReceiveActivity and its runtime

    In my last post I showed how to self host the workflow runtime and still be able to use a Windows Communication Foundation and ReceiveActivity.

    Hosting the workflow runtime in a WorkflowServiceHost is nice but in all likelihood you will also need to configure the workflow runtime itself and add some WorkflowRuntimeService to it. So how to do this when you never actually create the workflow runtime yourself?

    There are two possible ways to go about this depending if you prefer to use code or a configuration file. Lets first look at the code option as it is easier to see all the working parts. In the case of a WCF hosted workflow runtime the WorkflowRuntimeBehavior is the WCF ServiceBehavior that is actually responsible for creating the WorkflowRuntime. Fortunately getting a reference to it, and thereby the WorkflowRuntime, isn't hard.

    // Create the host

    WorkflowServiceHost host = new WorkflowServiceHost(typeof(Workflow1));

    // Retreive the WF behavior

    WorkflowRuntimeBehavior workflowRuntimeBehaviour =

    host.Description.Behaviors.Find<WorkflowRuntimeBehavior>();

    // Retreive the WF runtime

    WorkflowRuntime workflowRuntime = workflowRuntimeBehaviour.WorkflowRuntime;

    // Create and add the SqlWorkflowPersistenceService

    SqlWorkflowPersistenceService persistenceService =

    new SqlWorkflowPersistenceService(connectionString);

    workflowRuntime.AddService(persistenceService);

    // Start listening

    host.Open();

     

    Doing the same in a configuration file isn't hard either. The main problem is that a app.config isn't compiled so it's a bit easier to make a typo and not catch it until runtime.

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <system.serviceModel>

    <!-- Details ommited -->

    <behaviors>

    <serviceBehaviors>

    <behavior name="WorkflowConsoleApplication1.Workflow1Behavior" >

    <!-- Details ommited -->

    <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=WorkflowPersistence;Integrated Security=True;Pooling=False"

    LoadIntervalSeconds="1"

    UnLoadOnIdle= "true" />

    </services>

    </workflowRuntime>

    </behavior>

    </serviceBehaviors>

    </behaviors>

    </system.serviceModel>

    </configuration>

    This configuration file is basically the same as in the previous post except that contains a workflowRuntime element inside of the service behavior. This workflowRuntime contains the services collection where you can add any services you need.

     

    Enjoy!

    www.TheProblemSolver.nl
    http://wiki.WindowsWorkflowFoundation.eu

  • ReceiveActivity and self hosting WCF

    One of the new, and pretty cool, Windows Workflow Foundation features is the ReceiveActivity that unleashes the power of Windows Communication Foundation to Windows Workflow Foundation. Getting started with a ReceiveActivity is quite simple as long as you start with a sequential Workflow Service Library.

    The new service host for Windows Communication Foundation services makes life good as it means you can test a workflow without creating a host application or resorting to IIS.

    But sometimes you just want to host the workflow runtime yourself and still use the ReceiveActivity. So how to go about and do that?

    For a normal WCF host you would use an instance of ServiceHost but with a ReceiveActivity that isn't quite going to cut it as the host needs some awareness of WF and ServiceHost is very generic. So instead add a reference to System.WorkflowServices and create an instance of WorkflowServiceHost. The syntax is the same so no surprises there:

    WorkflowServiceHost host = new WorkflowServiceHost(typeof(Workflow1));
    host.Open();
    Console.WriteLine("Press enter to stop.");

    Console.ReadLine();

     

    The app.config contains the runtime configuration but all of it is pretty standard WCF stuff so no surprises:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <system.serviceModel>

    <services>

    <service name="WorkflowConsoleApplication1.Workflow2" behaviorConfiguration="WorkflowConsoleApplication1.Workflow2Behavior">

    <host>

    <baseAddresses>

    <add baseAddress="http://localhost:8731/Design_Time_Addresses/WorkflowConsoleApplication1/Workflow2/" />

    </baseAddresses>

    </host>

    <endpoint address=""

    binding="wsHttpContextBinding"

    contract="WorkflowConsoleApplication1.IMyContract">

    <identity>

    <dns value="localhost"/>

    </identity>

    </endpoint>

    <endpoint address="mex"

    binding="mexHttpBinding"

    contract="IMetadataExchange" />

    </service>

    </services>

    <behaviors>

    <serviceBehaviors>

    <behavior name="WorkflowConsoleApplication1.Workflow2Behavior" >

    <serviceMetadata httpGetEnabled="true" />

    <serviceDebug includeExceptionDetailInFaults="false" />

    <serviceCredentials>

    <windowsAuthentication

    allowAnonymousLogons="false"

    includeWindowsGroups="true" />

    </serviceCredentials>

    </behavior>

    </serviceBehaviors>

    </behaviors>

    </system.serviceModel>

    </configuration>

     

    Enjoy!

    www.TheProblemSolver.nl
    http://wiki.WindowsWorkflowFoundation.eu

  • Software Developer Event on March 28th

    Next march 28 we are hosting another SDE event in Ede, the Netherlands. There is an impressive list of speakers and sessions, check it out here. I will be doing a session about the new Workflow Foundation features in the .NET framework 3.5. These new features, also known as Silver, enable workflows to work together with Windows Communication Foundation (WCF) in a real nice and intuitive manner Smile

    And just to get a taste here is a screen cast made during the last SDE held in December. The screen cast is in Dutch and for SDN members only!

    Enjoy

  • Visual Studio 2008 and .NET Framework 3.5 Training Kit

    Looking for more information about VS2008 and .NET 3.5?

    I suspect you might just be as there is a ton of new functionality and with the pace of everything coming out it isn't likely that you know it all Smile

    To help learn the new stuff Microsoft has put a Visual Studio 2008 and .NET Framework 3.5 training kit together with lots of labs and presentations. Just go through the list and check what you would like to know more about.

    You can download the trainings kit from here.

    Enjoy!

     

  • Long running workflows and the ReceiveActivity

    Using a ReceiveActivity is a great way of exposing a workflow via a WCF proxy.

    Get started by creating a new project based upon "Sequential Workflow Service Library". This is found in the WCF projects node instead of the Worflow projects node!

    Create a service interface, mine is nice and simple and add a few ReceiveActivity to the workflow and hoop up the service interface to the activities. No big deal so far and we can test things by just pressing F5 and having the WCF Test Client. Actually you can only call functions that are hooked up to an ReceiveActivity with the CanCreateInstance set to True so the WCF Test Client might not be all that useful here if you use multiple ReceiveActivity that are part of a single workflow or conversation.

    Next step is to create a simple console application as a client with the following code:

    Sub SimpleDemo()

    Dim proxy As New ServiceReference1.DoStuffClient

    Console.WriteLine(proxy.AskQuestion("Is this cool?"))

    proxy.AllDone()

    End Sub

     

    This code works just fine Smile until we decide to split it up and recreate the WCF proxy object for part two like this Sad:

    Private Sub Part1()

    Dim proxy As New ServiceReference1.DoStuffClient

    proxy.GetStarted("Maurice")

    Console.WriteLine(proxy.AskQuestion("To be or not to be?"))

    End Sub

     

    Private Sub Part2()

    Dim proxy As New ServiceReference1.DoStuffClient

    Console.WriteLine(proxy.AskQuestion("Is this cool?"))

    proxy.AllDone()

    End Sub

     

    In this case the second proxy object doesn't work at all and we get a FaultException with the message "There is no context attached to incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized."

    So what gives? Well the WCF service needs to know which workflow the request needs to be routed to and uses the WorkflowInstanceId to do so. When you create a proxu and do the first call this WorkflowInstanceId is automatically added and resent with the next request. So we need to retrieve this WorkflowInstanceId and, when we create the second proxy object, add it again. Doing so turns out to be pretty simple and only takes a few extra lines of code:

    Private _instanceId As String

     

    Private Sub Part1()

    Dim proxy As New ServiceReference1.DoStuffClient

    proxy.GetStarted("Maurice")

    Dim contextManager As IContextManager = _

    proxy.InnerChannel.GetProperty(Of IContextManager)()

    Dim context As Dictionary(Of String, String) = _

    contextManager.GetContext()

    _instanceId = context("instanceId")

    Console.WriteLine(proxy.AskQuestion("To be or not to be?"))

    End Sub

     

    Private Sub Part2()

    Dim proxy As New ServiceReference1.DoStuffClient

    Dim contextManager As IContextManager = _

    proxy.InnerChannel.GetProperty(Of IContextManager)()

    Dim context As New Dictionary(Of String, String)

    context.Add("instanceId", _instanceId)

    contextManager.SetContext(context)

    Console.WriteLine(proxy.AskQuestion("Is this cool?"))

    proxy.AllDone()

    End Sub

     

    Basically what we need to do is retrieve the workflow instanceId from the context that is returned with the first call and save that. Next time we create a new proxy object we need to store the same instanceId in the request context before we actually use it and we are good to go Smile Setting the instaceId is actually done through a ClientContextProtocol object which is returned as an IContextManager inside of the channel properties. Check the bold lines in the previous code sample.

    So why is this so important?

    Well one of the most powerful features of Workflow Foundation is its capability to have long running workflows. Now long running workflows would not be very useful if the client application needs to keep its proxy alive for as long as it need to communicate with the workflow. Guess that would make "long running" a very relative thing. But with this technique all the client has to do is save the workflow instanceId somewhere, perhaps a database table, and it can reconnect to the same workflow at a later point in time.

    Enjoy!

  • The Future of BizTalk/WCF/WF

    Walter Michel commented on my recent entry on the BizTalk and WCF Messaging Models and asked if I had some guesses as to what the architecture of a future BizTalk version might look like in regards to WF/WCF integration. I think that, at this point in time, it is anybody's guess what it might look like, as it is just too early to tell. Honestly, I don't know what it might end up looking like, and I can't even say I can make an educated guess (and there are people with far more criteria for making such educated guesses than me, such as Jon Flanders ). Instead, I'll address the question in a different way, by mentioning what I consider a few challenges I see regarding the integration and other things like that. The Impact of Significant Architecture Changes One key aspect of the whole integration process between the three technologies is what the impact of significant changes to the core BizTalk architecture. Microsoft already went down that path during the transition between BizTalk 2002 and 2004, and while those of us developing BizTalk solutions are extremely grateful for the benefits that the new architecture brought over, companies with large investments in BizTalk 2000/2002 solutions were not so happy. For most of them, going to BizTalk 2004/2006 meant a complete rewrite of their integration solutions, and that can be very expensive, and though to justify to the business side, not only because of cost, but also because of the associated risks. With BizTalk 2004/2006, BizTalk brought over not only a significantly revamped platform, but also a new, effective, and very welcome extensibility model that has been tested with time. That's why the current core product architecture has been good for three release cycles already, and the fact that even complex things like WCF could be integrated without significant changes to it is pretty substantial. A lot of Microsoft clients and partners have made significant investments in that architecture and its not clear how that investment might be preserved (or at least their loss mitigated a bit) if significant architecture changes happen. I'm pretty sure the people at the Connected Systems Division at Microsoft are aware of this, and from my own, outside perspective, I can only say that it seems like a daunting and complex decision to make. Whatever way they decide to go, it's not going to be easy. So, what happens if the complex changes do become a reality? We can only hope that good migration tools are not left by the side; but even with those migration tools, you'd probably be looking at a complete rewrite scenario again for the most part. Messaging In my previous entry, I commented that the current WCF integration in BizTalk 2006 R2 leverages the existing BizTalk messaging extensibility model (the adapter framework) on top of the messaging engine. However, I think that in the long run, keeping both is probably not the best solution. Despite their differences, there's still a lot of common ground and responsibilities Read More...
  • Harry sticks up for the magic method

    Here - I can certainly understand his points. For me it comes down to two things: 1) The design of ServiceHostBase isn't as clean as I think it should given its intended purpose (to allow WCF Services to be exposed w/o a .NET Type associated with it). 2) The exception. I wouldn't hate the design as much if a) the exception wasn't a blatant lie, and b) they actually documented that you need to call InitializeDescription from your constructor. Check out my BizTalk R2 Training . Read More...
  • Magic Methods (or the basics of deriving from ServiceHostBase)

    Considering my history using ASP and COM – you can imagine I’ve always been a fan of interface-based design. Of course, I’m not a religious zealot of any sort, so I’ve always been comfortable with the idea of abstract base classes as another perfectly valid way to create pluggable, extensible systems. This post is about one such pluggable system which utilizes abstract base classes – and how that kind of design can just be stupid (not based on the concept of abstract base classes, but just based on dumb design of such a system). Harry has been bugging me to post about creating classes that derive from ServiceHostBase, which I have done quite a few times in the past year or so. The next technical post I make after this one will be about the ins and outs of creating a class that derives from ServiceHostBase (specifically to host workflows as WCF Endpoints), but I’ve had this post on my chest for a while and I just had to let it out (although as I am writing the post I am finding that it is a pretty decent introduction to ServiceHostBase – interspersed with slight vitriol). One of the things I strive for whenever I design an abstract base class is to make sure that it is as simple as possible to derive from and implement that base class. One of the great features in Visual Studio (VS) is that via reflection VS can determine what methods *must* be implemented for a particular base class when you build a derived class. Let’s take a simple example. Imagine a base class named “Base” Read More...
  • Microsoft DevDays day 2

    We are just finished with the last day of the 2007 Microsoft DevDays and looking back it would say it was a was a great success. Lots of people, from what I hear almost 25% more than last year, attended and from what I heard most where more than happy. I attended some more good sessions today and did my Worflow Activity development Chalk&Talk. Not all that many people turned up for the C&T session but we still had some interesting discussions. Marcel also did a Workflow presentation including a quick demo of his impressive WCF activities for Workflow Foundation which you can find here.

    I am already looking forward to next year's DevDays event.

    And yes I did swipe my banner and it's in my office now Smile

     

More Posts Next page »

<July 2008>
SuMoTuWeThFrSa
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us