Handling comma separated values inside a map, part I

Handling comma separated values inside a map, part I

Hi all

Some times people need to convert a list of elements into a comma separated list of
values. In the forums this questions arises every now and then, so here goes a solution.

Suppose this input:

<ns0:MultipleElementsRoot xmlns:ns0="http://MapCommaSeparatedValue.MultipleElementsSchema">

  <MyField>Jan</MyField>

  <MyField>Eliasen</MyField>

  <MyField>BizTalk</MyField>

</ns0:MultipleElementsRoot>

And I want this output:

<ns0:CommaSeparatedRoot xmlns:ns0="http://MapCommaSeparatedValue.CommaSeparatedSchema">

  <CommaField>Jan,Eliasen,BizTalk</CommaField>

</ns0:CommaSeparatedRoot>

Inside a map I would handle it like this (2 approached, that share the first two functoids):

multipletocomma

The reoccurring element is used as input to a string concatenate functoid. The functoid
takes a comma as the second input. The output of the concatenate functoid is then
used as input for a cumulative concatenate functoid, effectively creating a comma
separated list of values. The issue with this list is, that it will have a comma at
the end of the line, which needs to be removed.

One way of doing this is to use three functoids to pull this last comma away. First,
I take the length of the string, then I subtract one from that, and use the string
extract functoid to extract the string beginning at position 1 and ending at (length
– 1) and send that to the destination element. Works like a charm.

Now, plenty of people out there (Henrik, you know who you are) would have no moral
qualms using a C# scripting functoid to get rid of the extra comma. Like this:

public string RemoveLastComma(string input)

{

  return input.Substring(0, input.Length-1);

}

That one scripting functoid would eliminate the last three functoids I added to remove
the last comma. But I still prefer the functoid way of doing it, mostly for maintenance
reasons. A new BizTalk developer looking at a map with lots of scripting functoids
has no idea what is happening, and even after looking at the code in all the scripting
functoids, he can’t remember what is happening in more than a couple of them. In my
opinion; Always use the built-in functoids if possible.

Now, just for the kick, I thought that some times the opposite could be the case –
going from a comma separated list to lots of elements. This, I cannot solve using
built-in functoids, unfortunately, so the map ended up like this:

commatomultiple

Just one scripting functoid. The type is an “Inline XSLT Call Template” and the script
is:

<xsl:template name="MyXsltSplitTemplate">

  <xsl:param name="param1" />

  <xsl:if test="$param1 != ”">

    <xsl:element name="MyField">

      <xsl:choose>

        <xsl:when test="contains($param1,
‘,’)">

          <xsl:value-of select="substring-before($param1,
‘,’)" />

        </xsl:when>

        <xsl:otherwise>

          <xsl:value-of select="$param1"
/>

        </xsl:otherwise>

      </xsl:choose>

    </xsl:element>

    <xsl:call-template name="MyXsltSplitTemplate">

      <xsl:with-param name="param1" select="substring-after($param1,
‘,’)" />

    </xsl:call-template>

  </xsl:if>

</xsl:template>

Basically, the function substring-before is used to get any string before a comma
and output it. If no comma is in the string, the string is output. The string to the
right of a comma is then used as a recursive call to the same template. Again; Works
like a charm 🙂

So, with any luck, this question can be answered by googling soon instead of asking
in the forums 🙂

Edit on 27’th June:

>



eliasen

Error: Cannot import wsdl:portType

Today I tried to access a WorkflowService hosted in IIS on Windows 7, and got this nice little error message:
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporterError: Schema with target namespace ‘http://schemas.microsoft.com/2003/10/Serialization/’ could not be found. XPath to Error Source: //wsdl:definitions[@targetNamespace=’http://tempuri.org’]/wsdl:portType[@name=’IService’]
[… lot more stuff ]
Warning: No code was […]

Dude, where’s my WCF content?

As you have probably noticed, the WCF Dev Center has changed quite a bit recently. If you are a returning visitor, you may be wondering where your favorite links went.

The driving principle behind the redesign is to better cater to the different audiences that visit our page. 

In its previous format, the WCF Dev Center catered very well to the return visitor looking for fresh content.  The various content feeds on the main page made it very easy to check back periodically and see new content.

However, our usage data shows that a lot of our traffic comes from first time visitors through search engines. Our redesign is an effort to present a friendlier face to those folks, and to help them find introductory materials.

The main page now has links to three main areas:

1) Get it: This page gives simple instructions for what you need to install to use WCF.  It also gives links to additional WCF Tools that are available in the Windows SDK and how to download them.

2) Get Started: This page has a streamlined set of content that we feel is most useful for programmers just getting started with WCF.  As part of this, we are introducing a new series of “Learning WCF Tutorials”.

3) Learn More: This page is the portal into all of the available learning resources and community content.  If you miss the old site, you might want to just bookmark this page as it is now the “one-stop shop” for experienced WCF programmers.

There are also two feeds on the main page: 

1) The “WCF Highlights” area where we will make important announcements such as Beta releases, important new content, and conference events.

2) The “What’s New” feed which will be a fast moving feed combining blog entries from the WCF Team Blog, syndicated MVP blogs, and the Social Network Bookmarking.

Please let us know what you think of the new design and make suggestions for any future improvements you’d like to see.

Workflow Tracking Profiles in .NET 4.0 Beta 1

Last week we introduced the new Workflow Tracking features in .NET 4.0.  In this post we’ll do a deep dive into tracking profiles and explain how to use them to track workflow execution in a flexible way. 

Tracking Profile Overview

Tracking profiles let you subscribe to events that are emitted by the runtime when the state of a Workflow instance changes.  Depending on your monitoring needs you may craft a profile that is very coarse, subscribing to a small set of high level state changes on a Workflow.  On the other hand you may create a very granular profile whose output is rich enough to reconstruct the execution later.  Tracking profiles can satisfy these extreme scenarios and anything in between.

Tracking profiles manifest themselves in one of two ways.  You can create tracking profiles programmatically in .NET or configure them as XML elements in the <system.serviceModel> section of a standard .NET configuration file.  This post covers configuration based profiles.  Here is an example tracking profile in .NET 4.0 Beta 1:

<system.serviceModel>

   

    <tracking

      <trackingProfile name="High_Level_Tracking_Profile">

        <workflow>

          <workflowInstanceQuery>

            <states>

              <state name="Started"/>

              <state name="Completed"/>

            </states>

          </workflowInstanceQuery>

        </workflow>

      </trackingProfile>       

    </profiles>

  </tracking>

   

</system.serviceModel

 

Tracking Profile Structure

Tracking profiles are structured as declarative subscriptions to events, or tracking queries that let you “query” the Workflow Runtime for specific event records.  There are a handful of query types that let you subscribe to different classes of events.  Here are the most common query types that you can try out in .NET 4.0 Beta 1:

%u00b7         WorkflowInstanceQuery – Use this to track Workflow instance lifecycle changes like Started and Completed.

%u00b7         ActivityQuery – Use this to track lifecycle changes of the activities that make up a Workflow instance.  For example, you may want to keep track of every time the “Send E-Mail” activity completes within a Workflow instance.

%u00b7         FaultPropagationQuery – Use this to track the handling of faults that occur within an activity.  This event occurs each time a FaultHandler processes a fault.

%u00b7         UserTrackingQuery – Use this to track events that you define in your code activities.  There will be a follow up to this post that shows you how to create user tracking records.

Variable Extractions

When tracking the execution of a Workflow it is often useful to extract data.  This provides additional context when consuming the tracking records post execution.  Tracking profiles make this easy.  In .NET 4.0 you can extract variables from any activity in a Workflow.  The following example activity query comes from the monitoring hands on lab that shipped with the WCF and WF samples for .NET 4.0 Beta 1.  It shows how to extract the “StockSymbol” variable whenever the “GetStockPrice” activity completes.

<activityQueries>

  <activityQuery activityName="GetStockPrice">

    <states>

      <state name="Closed"/>

    </states>

    <variableQueries>

      <variableQuery variable="StockSymbol"/>

    </variableQueries>

  </activityQuery>            

</activityQueries>

 

Annotations

Annotations in Workflow 4.0 let you arbitrarily tag tracking records with a value that can be configured after build time.  For example, you might want several tracking records across several Workflows to be tagged with “Data Center” == “Contoso Data Center”.  This makes it easy to find all records with this tag when querying tracking records later.  To accomplish this, you would add an annotation to a tracking query like this:

<activityQueries>

  <activityQuery activityName="GetStockPrice">

   <states>

      <state name="Closed"/>

    </states>

    <annotations>

     <annotation name="Data Center" value="Contoso Data Center"></annotation>

    </annotations>

  </activityQuery>

</activityQueries>

 

What’s Next

In the next post in the series, we will talk about the extensibility of Workflow tracking  in .NET 4.0.  This topic will dive into the following concepts:

%u00b7         Programmatically emit your own tracking events by creating UserTrackingRecords.

%u00b7         Programmatically consume events within the runtime by creating custom TrackingParticipants.

%u00b7         Programmatically create tracking profiles in .NET.

RESTFul Services in Silverlight – CT Code Camp June 2009

Downloade thePresentation and Code
The Connecticut User Group organized a full day code camp event in Bloomfield, CT. The topic I presented on was “RESTFul Services and Silverlight”. The presentation was organized around the following main topics:

Web Services via SOAP
RESTFul Services
Creating a WCF RESTFul Service
Consuming a Custom WCF RESTFul Service in Silverlight

The attached slide deck will […]