I'm Keyvan Nayyeri, a 25 years old Ph.D. student at
the Computer Science department of
the University of Texas at San Antonio.
I'm also
a Software Architect and Developer and previously held a B.Sc.
degree in Applied Mathematics.
This is my blog where I publish content about various topics specifically Programming Languages and Compilers, Software
Engineering and Programming.
Last week I wrote about an open source project for WCF activities for Windows Workflow Foundation and mentioned that there is a default activity to invoke webservices from them. In this post I want to talk about this topic.
To illustrate my purpose I use a simple webservice to get a birthdate and return the age as integer value. Code for webservice is shown below. Later I'll use this webservice to invoke its GetAge() method from my sample workflow.
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service()
{
}
[WebMethod]
public int GetAge(DateTime BirthDate)
{
int diff = DateTime.Now.Year - BirthDate.Year;
return (DateTime.Now.Month < BirthDate.Month ||
((DateTime.Now.Month == BirthDate.Month)
&& (DateTime.Now.Day < BirthDate.Day))) ? --diff : diff;
}
}
Is it C#?!
InvokeWebService is a default activity in Windows Workflow and allows you to invoke webservices from your workflows easily. You can simply drag and drop this activity to your workflow to start using it. Once you drop this activity to your workflow Add Web Reference dialogue appears to ask for a webservice address. You can put your webservice URL to add a web reference. In this case it will generate the proxy class and configuration files and sets some properties for you automatically. You can also cancel this dialogue. In this case you have to write your own code for proxy class and set all properties manually.
InvokeWebService activity requires four (or more) properties to be set for it:
Now I drag and drop an InvokeWebService activity to my sample workflow and use Add Web Reference dialogue to generate my proxy class automatically. After this, I choose the right name for my MethodName property (GetAge) and create two new members for my ReturnValue (age) and BirthDate (birthDate) parameters. Windows Workflow generates codes for these two new members automatically. At this point my activity can work and invoke my webservice to pass the birthDate parameter and get the result and store it in age property. But I'm interested to invoke webservice based on user's birthdate so I have to get the birthdate from the user and show the result in console. In order to do this I add two code activities before (codeActivity1) and after (codeActivity2) my invokeWebServiceActivity1 activity. My final workflow looks like this:
In codeActivity1 I write a simple code to ask for birthdate from user and read the value of birthDate property from console.
private void codeActivity1_ExecuteCode_1(object sender, EventArgs e)
{
Console.Title = "Age Service";
Console.WriteLine("Enter your birthdate:");
this.birthDate = DateTime.Parse(Console.ReadLine());
}
In codeAcitivity2 I write another simple code to write the value of age property in console.
private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("You're {0} years old.", age.ToString());
Console.ReadLine();
}
So the final code for my workflow (with auto-generated codes for input and output parameters) is this:
public sealed partial class Workflow1 : SequentialWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
}
public static DependencyProperty birthDateProperty =
DependencyProperty.Register("birthDate", typeof(System.DateTime),
typeof(InvokeWebserviceSample.Workflow1));
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Parameters")]
public DateTime birthDate
{
get
{
return ((System.DateTime)(base.GetValue(InvokeWebserviceSample.Workflow1.birthDateProperty)));
}
set
{
base.SetValue(InvokeWebserviceSample.Workflow1.birthDateProperty, value);
}
}
public static DependencyProperty ageProperty =
DependencyProperty.Register("age", typeof(System.Int32),
typeof(InvokeWebserviceSample.Workflow1));
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Parameters")]
public Int32 age
{
get
{
return ((int)(base.GetValue(InvokeWebserviceSample.Workflow1.ageProperty)));
}
set
{
base.SetValue(InvokeWebserviceSample.Workflow1.ageProperty, value);
}
}
private void codeActivity1_ExecuteCode_1(object sender, EventArgs e)
{
Console.Title = "Age Service";
Console.WriteLine("Enter your birthdate:");
this.birthDate = DateTime.Parse(Console.ReadLine());
}
private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("You're {0} years old.", age.ToString());
Console.ReadLine();
}
}
Now if I run my workflow and enter my birthdate, it can show my age correctly:
The other aspect of webservices is around sessions. You know that ASP.NET webservices (ASMX services) support cookies sessions via cookies in HTTP protocol out of the box and you don't need to take care about details in your webservices. In your workflows sometimes you want to call a webservice several times and need to keep sessions during all these calls. Thankfully InvokeWebService activity comes with SessionID property. This property helps you to keep sessions for all your calls to a webservice from different activities. To use this property you can simply put a unique string as its value for all activities (simply put a GUID to make sure its unique between all activities). Windows Workflow will do the rest and makes sure that your activities use same sessions during all calls (if webservice itself supports sessions).
+ After some weeks I wrote something with my old blogging style! Blogging for future was a good experience during the last month!
Now playing: Chris De Burgh - Saint Peter's Gate
DotNetKicks.com
Mar 30, 2007 1:00 AM
#
Keyvan Nayyeri
Apr 05, 2007 6:41 AM
#
ElsieQ
Mar 17, 2008 1:13 PM
#
Is there an easy way to call a WCF web service from a simple, sequential WWF workflow on .NET 3.0/VS 2005 platform? I know that .NET3.5/VS2008 has made this integration seamless but I'm stuck trying to get it to work on .NET 3.0/ VS2005.
Leave a Comment