Windows 7: Create .Net Flickr Federated Search Connector
Windows 7 makes searching for content much easier with Federated Search. In this post I’ll talk about how to how to create a Flickr Federated Search Providers in .Net.
Before We Start
This sample uses Flickr API through Flickr.Net. In order to build your own version of this Flickr Federated Search Connector:
Create a new ASP.Net Web Application
Create a new ASP.Net Web Application with Visual Studio.
Add the Flickr.Net project (called FlickrNet.csproj) to your solution, and add a reference to it from your web application.
Add the Flickr API and Secret Key’s to your web.config in the AppSettings section:
<appSettings>
<add key="flickr_api_key" value="923422ab4225345dfgdb777daf46"/>
<add key="flickr_secret" value="aa8b23fsdfhyc3beda"/>
</appSettings>
Create the Flickr Search Provider
The following provider will be executed by the Windows Explorer client using HTTP GET, and will receive several parameters from it:
http://localhost:52903/Search.aspx?q=TechEdIsrael2008&start=1&count=20
It will perform the search against Flickr, and return the response as RSS.
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>Flickr Search Results</title>
<item>
<title>IMG_0134c</title>
<link>http://farm4.static.flickr.com/3100/2682983091_7cea404dc4_m.jpg</link>
<description>show shadow dance techedisrael2008</description>
<pubDate>Sun, 20 Jul 2008 01:47:25 GMT</pubDate>
<media:content url="http://farm4.static.flickr.com/3100/2682983091_7cea404dc4_b.jpg"
type="image/jpeg" height="333" width="500" />
<media:thumbnail url="http://farm4.static.flickr.com/3100/2_7cea404dc4_t.jpg" />
</item>
<item>
...
</item>
</channel>
</rss>
Create a new Web Form called Search.aspx.
To make it easier to test the response, right click the web application, and open the Properties window. Go to the Web pane, select Search.aspx as the start page and provide the query parameters:
In the page markup, add a new asp:Repeater control that will define the template for each item in the response:
<asp:Repeater runat="server" ID="itemsRepeater">
</asp:Repeater>
In the page code behind, implement the logic that uses Flickr.Net to search for photos and bind the result to the repeater control:
protected void Page_Load(object sender, EventArgs e)
{
string flickrApiKey = WebConfigurationManager.AppSettings["flickr_api_key"];
string flickrSecret = WebConfigurationManager.AppSettings["flickr_secret"];
string searchTerm = Request.QueryString["q"];
int startPage = int.Parse(Request.QueryString["start"]);
int count = int.Parse(Request.QueryString["count"]);
Flickr flickr = new Flickr();
flickr.ApiKey = flickrApiKey;
flickr.ApiSecret = flickrSecret;
Photos photos = flickr.PhotosSearch(null, "", 0, searchTerm,
DateTime.MinValue, DateTime.MinValue, 0,
count, startPage, PhotoSearchExtras.All);
this.itemsRepeater.DataSource = photos.PhotoCollection;
this.itemsRepeater.DataBind();
}
In the code above I first grab the API and secret key’s from the configuration file and then, I extract the parameters from the query string. I create a new instance of the Flickr object, and perform the actual search for photos, providing the page number and the number of items in each page. Finally, I bind the returned photo collection the the repeater control.
Replace the html header and footer with RSS header and footer in Search.aspx.
Before:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Search.aspx.cs" Inherits="FlickrFederatedSearch.Search" %>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater runat="server" ID="itemsRepeater">
</asp:Repeater>
</div>
</form>
</body>
</html>
After:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Search.aspx.cs" Inherits="FlickrFederatedSearch.Search" %>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>Flickr Search Results</title>
<asp:Repeater runat="server" ID="itemsRepeater">
</asp:Repeater>
</channel>
</rss>
Set the ItemTemplate of the Repeater control to display the photos data according to the output format:
<asp:Repeater runat="server" ID="itemsRepeater">
<ItemTemplate>
<item>
<title><%# Eval("Title") %></title>
<link><%# Eval("SmallUrl")%></link>
<description><%# Eval("CleanTags")%></description>
<pubDate>
<asp:Literal runat="server"
text='<%# ((FlickrNet.Photo)Container.DataItem).DateTaken.ToString("R") %>' />
</pubDate>
<media:content url='<%# Eval("LargeUrl")%>' type="image/jpeg" />
<media:thumbnail url='<%# Eval("ThumbnailUrl")%>' />
</item>
</ItemTemplate>
</asp:Repeater>
Run the application. The browser should navigate to Search.aspx passing all the relevant query parameters. The response should be an RSS feed that contains items per photos found.
Creating the Flickr Federated Search Connector
Add a new Xml file to the project and name it FlickrFederatedSearch.osdx (stands for OpenSearch Description Xml). This file contains the data that Windows Explorer needs to order to perform the search against the search service.
<?xml version="1.0" encoding="utf-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Flickr Federated Search</ShortName>
<Url type="application/rss+xml"
template="http://.../Search.aspx?q={searchTerms}&start={startPage}
&count={count}" />
</OpenSearchDescription>
Notice in the above xml that the parameters are taken from some predefined names ({searchTerms}, {count} etc.), and the ampersands (&) are Html encoded.
Right click the .osdx file, and select Open With.

In the Open With dialog, select Windows Explorer.
In the Add Search Connector dialog, click Add.
Now, Flickr Federated Search appears in the Favorites section in Windows 7 Explorer and you can use it for searching items.
Summary
In this post I’ve talked about how to create a Flickr Federated Search Connector for Windows 7 in .Net. The above provider provides basic features and can be enhanced with more capabilities described in the Windows 7 Federated Search Provider Implementer’s Guide.
Enjoy!
Getting Started with jQuery in Visual Studio 2008

In this post I’ll talk about adding jQuery IntellSense in Visual Studio 2008, and how to add jQuery to a simple Web Application inside Visual Studio 2008.
jQuery IntelliSense in Visual Studio 2008 - KB946581
In order to use jQuery in Visual Studio 2008 with IntelliSence a hotfix for Visual Studio 2008 must be installed:
- Download the hotfix from Connect
- Run the executable and extract its contents to a folder in your hard drive.
- Make sure all instances of Visual Studio 2008 are closed, and run VS90-KB946581.exe from the above folder.
Download the Latest jQuery Library + Documentation
To use jQuery in Visual Studio 2008, and enjoy its IntelliSense, you should download 2 javascript files. One contains the actual jQuery library, and the second contains the library with documentation for Visual Studio 2008 to display its IntelliSense.
- Go to jQuery Official Download Page
- Scroll down and find the Current Release section.
- Download the Uncompressed version (jquery-1.2.6.js) and the documentation for Visual Studio (jquery-1.2.6-vsdoc.js).
Using jQuery in a Visual Studio 2008 Web Application
In a new Web Application or inside an existing one, add the jQuery scripts into a certain folder.
In a web page (or a master page), add a reference to the jQuery library:
<head runat="server">
<title>jQuery Sample</title>
<script src="scripts/jquery-1.2.6.js"
type="text/javascript" ></script>
</head>
Then, in any javascript function you can start using jQuery functions and enjoy the IntelliSense in Visual Studio 2008.
A Simple Example of Using jQuery Functions
For example, Assuming that you have a page with the following content in it:
<form id="form1" runat="server">
<div>
<input type="text" class="inputs" id="txtName"
value="Enter Text Here" />
<input type="button" class="inputs" id="btnSubmit"
value="Click Me" onclick="handleButtonClick();" />
</div>
</form>
This form contains a single textbox followed by a button.
The handleButtonClick() function handles the button onclick event.
<script type="text/javascript">
function handleButtonClick() {
}
</script>
The way jQuery works is by selecting DOM elements and then doing something with them, such as executing a function or applying some properties. For example:
<script type="text/javascript">
function handleButtonClick() {
$("#txtName").css("border", "solid 2px red");
}
</script>
The above method uses the selector function $ to select DOM elements (in this case – a single element with id = txtName) and to apply a style property of a red border. Running this page and clicking the button results in this output:
Summary
In this post I talked about the steps you should follow in order to use jQuery in Visual Studio 2008 with InstelliSense support. Then, we used jQuery in a simple web application.
Twitter API From C#: Getting a User’s Time Line
From Twitter API Documentation page:
User Timeline:
Returns the 20 most recent statuses posted from the authenticating user:
http://twitter.com/statuses/user_timeline.xml
It's also possible to request another user's timeline. For example:
http://twitter.com/statuses/user_timeline/bursteg.xml
Making an HTTP Request
Since all the API is expressed in REST, I figured out that I need a simple reusable method to perform HTTP requests. This method takes the URL and the method (GET or POST), gets the credentials from the configuration file and makes the request.
private string PerformRequest(string method, string url)
{
string user = ConfigurationManager.AppSettings["user"];
string password = ConfigurationManager.AppSettings["password"];
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = method;
request.Credentials = new NetworkCredential(user, password);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
reader.Close();
return responseString;
}
Just for the simplicity, I also added the following methods:
private string Post(string url)
{
return PerformRequest("POST", url);
}
private string Get(string url)
{
return PerformRequest("GET", url);
}
Getting a User’s Time Line from Twitter
Using the following code, you can get a user’s timeline from twitter in xml format:
string url = string.Format("http://twitter.com/statuses/friends/{0}.xml", user);
string response = Get(url);
This call returns the following piece of xml:
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
<created_at>Sat Nov 15 10:08:15 +0000 2008</created_at>
<id>1006846483</id>
<text>Testing "posts" #devacademy3</text>
<source>web</source>
<truncated>false</truncated>
<in_reply_to_status_id></in_reply_to_status_id>
<in_reply_to_user_id></in_reply_to_user_id>
<favorited>false</favorited>
<user>
<id>6849932</id>
<name>Guy Burstein</name>
<screen_name>bursteg</screen_name>
<location></location>
<description></description>
<profile_image_url>http://.../Guy_Burstein_Small_normal.jpg</profile_image_url>
<url>http://blogs.microsoft.co.il/blogs/bursteg</url>
<protected>false</protected>
<followers_count>42</followers_count>
</user>
</status>
<status>
...
</status>
</statuses>
As we can see, this response is an array of statuses, each contains the details about the user who posted it.
Extracting the Data
With my favor to LINQ to XML, I used it to extract the data that I was interested in, and construct CLR objects that I can easily work with.
XDocument document = XDocument.Parse(response, LoadOptions.None);
var query = from e in document.Root.Descendants("status")
select new UserStatus
{
UserName = e.Element("user").Element("name").Value,
ProfileImage = e.Element("user").Element("profile_image_url").Value,
Status = HttpUtility.HtmlDecode(e.Element("text").Value),
StatusDate = (e.Element("created_at").Value.ParseDateTime())
};
First, I parsed an xml document from the response string. Then, I created a list of UserStatus objects from the contents of the response xml.
public class UserStatus
{
public string UserName { get; set; }
public string ProfileImage { get; set; }
public string Status { get; set; }
public DateTime StatusDate { get; set; }
}
Few things to note about the above code:
1. HttpUtility.HtmlDecode is being used in order to get a readable text. The response contained text like “Testing "posts" #devacademy3” and this method (in System.Web) converts it to “Testing “posts” #devacademy3”.
2. The ParseDateTime() method on the element’s value is an extension method I created in order to parse a DateTime from the special string representation of the time the status was posted:
Sat Nov 15 10:08:15 +0000 2008
This method looks like:
public static class StringExtensions
{
public static DateTime ParseDateTime(this string date)
{
string dayOfWeek = date.Substring(0, 3).Trim();
string month = date.Substring(4, 3).Trim();
string dayInMonth = date.Substring(8, 2).Trim();
string time = date.Substring(11, 9).Trim();
string offset = date.Substring(20, 5).Trim();
string year = date.Substring(25, 5).Trim();
string dateTime = string.Format("{0}-{1}-{2} {3}", dayInMonth, month, year, time);
DateTime ret = DateTime.Parse(dateTime);
return ret;
}
}
If you come up with another idea of how to parse this string into a DateTime object, please let me know.
Wrapping it up...
The final version of the GetUserTimeLine method looks like this:
public List<UserStatus> GetUserTimeLine(string user)
{
string url = string.Format("http://twitter.com/statuses/user_timeline/{0}.xml", user);
string response = Get(url);
XDocument document = XDocument.Parse(response, LoadOptions.None);
var query = from e in document.Root.Descendants("status")
select new UserStatus
{
UserName = e.Element("user").Element("name").Value,
ProfileImage = e.Element("user").Element("profile_image_url").Value,
Status = HttpUtility.HtmlDecode(e.Element("text").Value),
StatusDate = (e.Element("created_at").Value.ParseDateTime())
};
List<UserStatus> users = (from u in query
where u.Status != ""
orderby u.StatusDate descending
select u).ToList();
return users;
}
The techniques I’ve used here can be used in almost all the “get” methods of the REST API of Twitter.
Enjoy!
ASP.Net MVC on Windows Azure | ASP.Net MVC Web Role
When you install Windows Azure Tools for Visual Studio, you only get a project template for an ASP.Net Web Role. In this post I’ll talk about how to create a new ASP.Net MVC Web Role or move an existing ASP.Net MVC Application to Windows Azure.
There are 2 ways to do this:
Manually adding an ASP.Net MVC application as a Web Role (suitable both for a new ASP.Net MVC application and for an existing one). - Use a Project Template to simply create a new ASP.Net MVC Web Role (new ASP.Net MVC application only).
Creating a New ASP.Net MVC Web Role
The following steps apply both for creating a new ASP.Net MVC application and to moving an existing ASP.Net MVC application to Windows Azure.
1. Create an empty ASP.Net MVC Application (with or without a test project), or make sure you have an existing ASP.Net MVC application that you want to move to the Windows Azure.
2. Close this solution and create a new Blank Cloud Service. Make sure you start Visual Studio as an administrator because working with the Development Fabric requires that.
3. Add an existing project to the cloud service and select the ASP.Net MVC Application you have created earlier.
4. Right click the ASP.Net MVC project and select Unload Project.
5. When the project is unloaded, right click it and edit the project file.
6. The project file opens in the XML Editor.
<Project ToolsVersion="3.5" DefaultTargets="Build" ...>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
...
</PropertyGroup>
...
</Project>
Inside the PropertyGroup Element, add the RoleType element and mark this ASP.Net MVC project as a Web Role.
<Project ToolsVersion="3.5" DefaultTargets="Build" ...>
<PropertyGroup>
<RoleType>Web</RoleType>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
...
</PropertyGroup>
...
</Project>
7. Close this project file, and reload the project.
8. Since the ASP.Net MVC now runs on the Windows Azure Service Hosting environment and will probably use its services – add a reference to Microsoft.ServiceHosting.ServiceRuntime.dll.
9. Right click the Roles node in the project tree, and add a Web Role Project in the solution. Select the ASP.Net MVC project from the project list.
Now the ASP.Net MVC project is shown as a Web Role.
10. Since the Windows Azure provides us only with the default .Net Framework 3.5 SP1 assemblies, we must make sure we also copy the ASP.Net MVC Assemblies to the cloud. To do this, right click on each of the following references of the ASP.Net MVC application, and set the Copy Local property to True:
- System.Web.Abstractions
- System.Web.Mvc
- System.Web.Routing
That’s it. You can run the application to make sure that it is running on the Development Fabric.
Creating an ASP.Net MVC Web Role using a Project Template
Thanks to a great word done by the community, we can use a project template to do all the above steps for us. Here’s how to do this:
1. Download the project template from Codeplex at http://c4mvc.codeplex.com/.
2. Create a new project and select the Azure ASP.Net MVC template in the Community for MVC category.
This creates a new Cloud Service for Windows Azure with ASP.Net MVC Application as a Web Role.
Enjoy!
WF/WCF using Visual Studio 2010 and .NET Framework 4 Training Kit
The Microsoft WF/WCF using Visual Studio 2010 and .NET Framework 4 Training Kit includes presentations, hands-on labs, and demos. This content is designed to help you learn how to utilize the Visual Studio 2010 features and a variety of WF and WCF new features.
- Learn basic workflow creation, hosting and running , and test-drive workflow development.
- Get an introduction to workflow services, communication between workflows and content based correlation of workflow instances.
- Use the flexibility of Flowchart workflow activities to implement non-sequential workflows.
- Learn how to rehost the workflow designer in a WPF desktop application and customize it in several ways.
- Learn how you can leverage some of the main WF and WCF monitoring features to track application execution and troubleshoot problems with services when necessary.
- Learn how Service discovery allows you to locate services on the same subnet using ad hoc discovery, or using a proxy to establish connections with servers regardless of where they are.
This version of the training kit is compatible with Visual Studio 2010 Beta 1.
Download here.
WF 4.0: Long Running Custom Activities with Bookmarks and NativeActivity

This is another post in my WF 4.0: Custom Activities series. In a previous post I have talked about creating a code only custom activity that performs a simple task. In this post I’ll talk about creating a more complex activities that takes inputs from the calling program during their execution.
In the previous post WF 4.0: Code Only Custom Activities for Atomic Actions | CodeActivity, CodeActivity<T> I implemented the following activity for reading a string from the console.
public class ReadString2 : CodeActivity<string>
{
protected override void Execute(CodeActivityContext context)
{
string value = Console.ReadLine();
context.SetValue(Result, value);
}
}
While this activity will perform the task it is meant to do, it is blocking the calling thread and bad for scalability. In addition to that It is bound to getting the value from the console only, and it is not generic enough to support another input methods.
Enter Bookmarks.
Using NativeActivity for Complex Activities
To create a long running activity, add a new item of type Workflow Element item to the project. Notice that the default activity inherits from CodeActivity.
public class ReadString3 : CodeActivity
{
protected override void Execute(CodeActivityContext context)
{
}
}
To create complex activities such as long running activities, me need to change the base class and inherit from NativeActivity or NativeActivity<T>. In addition to that, there is a difference between the type of the parameter that the CodeActivity takes for the Execute method and the type that NativeActivity takes. Change the input parameter type from CodeActivityContext to ActivityExecutionContext.
public class ReadString3 : NativeActivity
{
protected override void Execute(ActivityExecutionContext context)
{
throw new NotImplementedException();
}
}
Enter Bookmarks
In previous versions of Windows Workflow Foundation we had the ExternalDataExchangeService and WorkflowQueue when we wanted to build a simple long running activity. In WF 4.0 this is much more simple to do using Bookmarks.
To use bookmarks we need to:
- Create a named bookmark and Implement a callback method
- Signal from the caller program
Register a Named Bookmak
The following activity registers a bookmark called “input” with a callback method called OnBookmarkCallback.
public class ReadString3 : NativeActivity
{
OutArgument<string> name;
public OutArgument<string> Name
{
get { return this.name; }
set
{
ThrowIfOpen();
this.name = value;
}
}
protected override void Execute(ActivityExecutionContext context)
{
context.CreateNamedBookmark("input", new BookmarkCallback(this.OnBookmarkCallback));
}
void OnBookmarkCallback(ActivityExecutionContext context, Bookmark bookmark, object obj)
{
this.Name.Set(context, (string)obj);
}
}
Signal the workflow from the caller program
In a previous post I have talked about the code that is needed to execute a workflow. Since we are now talking about long running workflows we will start with the default code that is generated for us when we create a new sequential workflow console application that uses the WorkflowInstance that lets know when the workflow instance is idle, and to resume a bookmark:
...
myInstance.Run();
//Get a string from the console and resume the bookmark called “input”
string input = Console.ReadLine();
myInstance.ResumeBookmark("input", input);
syncEvent.WaitOne();
...
The main program performs the input and delivers the value to the workflow. Using this approach:
- The main program is flexible in how it wants to get values from the user and any other input source
- The workflow becomes idle when it is waiting for the input and during that time not consuming any resources from the machine.
To query the available bookmarks in a workflow instance, we can use the following code:
IList bookmarks = myInstance.GetAllBookmarks();
foreach (BookmarkInfo info in bookmarks)
{
Console.Write(info.BookmarkName);
}
Enjoy!
WF 4.0: Code Only Custom Activities for Atomic Actions | CodeActivity, CodeActivity<T>

This is another post in my WF 4.0: Custom Activities series. In this post I’ll talk about creating a code only custom activity that performs a simple task. I’ll also use input and output parameters and talk about activities that returns a single value.
A Simple Code Activity
Lets start by building a simple activity that outputs a certain string to the console. To to that, lets add a new item of type Workflow Element (under the Workflow node in the item templates).
Visual Studio adds a new code file (remember – this is a code-only activity) with a class that inherits from the abstract class System.Activities.CodeActivity.
public class OutputString : CodeActivity
{
protected override void Execute(CodeActivityContext context)
{
}
}
To implement the logic of the atomic action, we just have to code it here. Notice that we don’t have to tell the runtime that the status of this activity is closed or something like this like we had to in WF 3.5.
public class OutputString : CodeActivity
{
protected override void Execute(CodeActivityContext context)
{
Console.WriteLine("Hello world");
}
}
After building the project, the new custom activity will appear in the Toolbox, and can be used in the workflow.

Adding Input Parameters to the Custom Activity
To add a new input parameter to the activity, we declare a InArgument<T> field and property where T is the type of the parameter.
public class OutputString : CodeActivity
{
InArgument<string> name;
public InArgument<string> Name
{
get { return name; }
set {
ThrowIfOpen();
name = value;
}
}
protected override void Execute(CodeActivityContext context)
{
Console.WriteLine("Hello, " + this.Name.Get(context));
}
}
Note that in the property setter implementation I am calling the base class’ ThrowIfOpen() method. This method throws an InvalidOperationException if the activity has already been prepared for execution and the value cannot be set.
Also note that in order to get the property value, we do not store the value in a private member in the class, but instead – we use the InArgument class and using the Get method passing it the activity context.
Output Parameters to Custom Activities
Lets create a simple activity that reads the name from the console.
public class ReadString : CodeActivity
{
OutArgument<string> outputString;
public OutArgument<string> Output
{
get { return outputString; }
set {
ThrowIfOpen();
outputString = value;
}
}
protected override void Execute(CodeActivityContext context)
{
string value = Console.ReadLine();
context.SetValue(Output, value);
}
}
Notice how the code required for an output argument is similar to the one required for an input argument. Also notice how we set the value back to the output value using the ActivityContext instance.
Activities with a Single Output Parameter - CodeActivity<T>
The above sample read a string from the console and placed the value in the output parameter. If this is the case we can also inherit from CodeActivity<T>:
public class ReadString2 : CodeActivity<string>
{
protected override void Execute(CodeActivityContext context)
{
string value = Console.ReadLine();
context.SetValue(Result, value);
}
}
Inheriting from CodeActivity<T> makes it more simple to write a custom activity that has a single output parameter. It has additional benefits which I’ll talk about in a subsequent post.
Summary
In this post I talked about creating a code only custom activities that performs a simple task. I have also talked about input and output parameters.
WF 4.0: How to Execute a Worklflow (WorkflowInvoker vs WorkflowInstance)
Note: This post is based on Visual Studio 2010 Beta 1 which is the latest version available in the time of writing this post, so by the time this technology ships, there are probably things that will be slight different.
There are two ways to execute a workflow:
- Using the WorkflowInstance class
- Using the WorkflowInvoker class
Execute Workflows using WorkflowInstace
When you create a new Sequential Workflow Console Application, Visual Studio creates the basic code needed to execute the workflow inside the Main method:
static void Main(string[] args)
{
AutoResetEvent syncEvent = new AutoResetEvent(false);
WorkflowInstance myInstance = new WorkflowInstance(new Sequence1());
myInstance.OnCompleted = delegate(WorkflowCompletedEventArgs e)
{
syncEvent.Set();
};
myInstance.OnUnhandledException = delegate(WorkflowUnhandledExceptionEventArgs e)
{
Console.WriteLine(e.UnhandledException.ToString());
return UnhandledExceptionAction.Terminate;
};
myInstance.OnAborted = delegate(WorkflowAbortedEventArgs e)
{
Console.WriteLine(e.Reason);
syncEvent.Set();
};
myInstance.Run();
syncEvent.WaitOne();
}
1. A workflow instance is created and gets a reference to the root activity of the workflow. The WorkflowInstance class lets us control the running instance of the workflow and exposes several methods for this such as Run(), Abort(), Cancel(), Load(), Unload etc.
2. Since the workflow execution is scheduled to another thread, we need to block the main thread until the workflow is completed or terminated. To do this, we:
- Create an AutoResetEvent initialized to false,
- Set the event to true when the workflow is completed, and
- In the main thread - wait for the workflow to complete before exiting the method.
3. In order to handle errors in the workflow such as exceptions or termination, in addition to handling the OnCompleted event, we are also handling the OnHandledException and OnAborted events. Note that when the workflow has an unhandled exception, the program can still decide how it wants to end the workflow execution, whether it is by aborting, cancelling or terminating the workflow. If the workflow is terminated, the OnCompleted event will also be raised.
Execute Workflows using WorkflowInvoker
WorkflowInvoker lets you invoke a workflow much more easily than the previous approach. It takes the instance of the workflow or activity to run and executes it synchronously.
WorkflowInvoker.Invoke(new Sequence1());
There are additional overloads of this method that takes parameters and a TimeSpan in which the workflow should complete within. I’ll talk in more details about passing parameters to workflow in a subsequent post, but in general this is all we have to know about WorkflowInvoker.
Choosing between WorkflowInstance and WorkflowInvoker
If you have a simple workflow that should run synchronously – use WorkflowInvoker. This is useful also in when unit testing workflows (more on this in a later post).
If you have a long running workflow that you want to control – persist, abort, cancel etc – use WorkflowInstance.
Enjoy!
WF 4.0: Building a Hello World Sequential Workflow

Note: This post is based on Visual Studio 2010 Beta 1 which is the latest version available in the time of writing this post, so by the time this technology ships, there are probably things that will be slight different.
Start Visual Studio 2010 Beta 1 and create a new Sequential Workflow Console Application.
After you click OK, visual studio creates the new projects and creates a new WF project, in which there are some things you should know about:
References:
- System.Xaml – Now that there are several technologies based on Xaml, this is a new Assembly in .Net Framework 4.0 that contains Xaml services such as serialization.
- System.Activities is the assembly that contains the implementation of WF 4.0, and as you can guess, the corresponding namespace is System.Activities and anything beneath it.
- System.Activities.Design contains the designers for the activities and the designer re-hosting implementation. Since the new designer is based on WPF, you can also note references to WindowsBase, PresentationCode and PresentationFramework.
- System.ServiceModel contains WCF implementation (as of .Net Framework 3.0) and now System.ServiceModel.Activities contains the activities used for Workflow Services (the integration between WF and WCF).
Sequence.xaml:
By default, workflows are created declaratively in WF 4.0 and represented in .xaml files with no code behind. If you open this file with an Xml editor, you will see it clearly.
<?xml version="1.0" encoding="utf-8" ?>
<p:Activity x:Class="HelloWorld.Sequence1"
xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/activities"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities"
xmlns:sadx="clr-namespace:System.Activities.Design.Xaml;assembly=System.Activities.Design"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<p:Sequence sad:XamlDebuggerXmlReader.FileName="C:\...\HelloWorld\Sequence1.xaml">
</p:Sequence>
</p:Activity>
The new WF Designer shows an empty sequence, representing an empty block of execution. Note the warning sign that says that the sequence has no child activities.
From the Procedural section in the Toolbox, drag the WriteLine Activity to the design surface.
Now, you get a warning that the Text property is not set. To set it, go the properties window, and open the Expression Editor. In WF 4.0 you use the Expression to set values to variables and parameters, and you can use either static values (like in this case) or VB. Yes! Expression are written in VB.
Type the text you want to display to the console and click OK.
Now, that the simple workflow is completed, you can use Ctrl + F5 to run it like you normally do.
Debugging a Workflow
The debugging experience when debugging a workflow in WF 4.0 is very similar to the debugging experience when using code. You can right click an activity the in designer and select Insert Breakpoint, or use F9 to do this.
Once you do this and run the workflow, the debugger highlights the current activity using a yellow border (similar to the yellow background for the current statement when debugging code).
Enjoy!
XAML in .Net 4.0: Attached Properties, IAttachedPropertyStore and AttachablePropertyServices
Note: This post is based on Visual Studio 2010 Beta 1 which is the latest version available in the time of writing this post, so by the time this technology ships, there are probably things that will be slight different.
In a previous post I’ve talked about XAML Serialization and Deserialization using XamlServices in .Net Framework 4.0. In this post I’ll add to my data classes support for Attached Properties, so that they will be extensible during serialization.
Implement System.Xaml.IAttachedPropertyStore interface
This interface should be implemented by classes that can store attached properties.
public interface IAttachedPropertyStore
{
int PropertyCount { get; }
void CopyPropertiesTo(KeyValuePair<AttachableMemberIdentifier, object>[] array,
int index);
bool RemoveProperty(AttachableMemberIdentifier mi);
void SetProperty(AttachableMemberIdentifier mi, object value);
bool TryGetProperty(AttachableMemberIdentifier mi, out object value);
}
The simplest way of implementing it, is using a Dictionary<AttachableMemberIdentifier, object> that holds the attached properties. For example, the Book class from the previous post that now implements IAttachedPropertyStore:
[RuntimeNameProperty("Name")]
[ContentProperty("Related")]
public class Book : IAttachedPropertyStore
{
public int ISBN { get; set; }
public string Name { get; set; }
private IList<Book> related = new List<Book>();
public IList<Book> Related { get { return this.related; } }
#region IAttachedPropertyStore Members
IDictionary<AttachableMemberIdentifier, object> attachedProperties =
new Dictionary<AttachableMemberIdentifier, object>();
public void CopyPropertiesTo(KeyValuePair<AttachableMemberIdentifier, object>[] array,
int index)
{
attachedProperties.CopyTo(array, index);
}
public int PropertyCount
{
get { return attachedProperties.Count; }
}
public bool RemoveProperty(AttachableMemberIdentifier member)
{
return attachedProperties.Remove(member);
}
public void SetProperty(AttachableMemberIdentifier member, object value)
{
attachedProperties[member] = value;
}
public bool TryGetProperty(AttachableMemberIdentifier member, out object value)
{
return attachedProperties.TryGetValue(member, out value);
}
#endregion
}
Use AttachablePropertyServices to Attach Properties to Stores
After adding support for Attached Properties to our object we can attach additional properties to it. This can be done directly with System.Xaml.AttachablePropertyServices class, but usually, we would prefer creating a class that provides strongly typed methods for those kinds of operations. For example, if we want to add more metadata to the book, such as an indication whether it is in stock or not we can create a class like this:
public class StockInfo
{
public bool InStock { get; set; }
public int Quantity { get; set; }
}
In order to store and retrieve the data from a class that implements IAttachedPropertyStore we can add the following static methods to the StockInfo class:
public class StockInfo
{
public bool InStock { get; set; }
public int Quantity { get; set; }
public static StockInfo GetStockInfo(Book book)
{
StockInfo stockInfo = null;
AttachablePropertyServices.TryGetProperty<StockInfo>(
book,
new AttachableMemberIdentifier(typeof(StockInfo), "StockInfo"),
out stockInfo);
return stockInfo;
}
public static void SetStockInfo(Book book, StockInfo stockInfo)
{
AttachablePropertyServices.SetProperty(
book,
new AttachableMemberIdentifier(typeof(StockInfo), "StockInfo"),
stockInfo);
}
}
Now, we can attach and retrieve the additional data from the instance:
Book book1 = new Book { Name = "First", ISBN = 123 };
StockInfo.SetStockInfo(book1, new StockInfo { InStock = true, Quantity = 27 });
StockInfo info = StockInfo.GetStockInfo(book1);
If we decided to serialize the instance with the attached properties assigned to it, we would get a serialized content like this:
<Book ISBN="123" Name="First" xmlns="clr-namespace:XamlSamples;assembly=XamlSamples">
<StockInfo.StockInfo>
<StockInfo InStock="True" Quantity="27" />
</StockInfo.StockInfo>
</Book>
Summary
In this post I extended my data class (Book) with additional properties using the Attached Properties support in Xaml: Implementing the IAttachedPropertyStore interface by the data class and setting and getting the values using AttachablePropertyServices.
XAML in .Net 4.0: Serialization and Deserialization using XamlServices
Note: This post is based on Visual Studio 2010 Beta 1 which is the latest version available in the time of writing this post, so by the time this technology ships, there are probably things that will be slight different.
In order to serialize and deserialize using XAML in .Net Framework 4.0 we have to reference a new assembly called System.Xaml.dll. Since XAML was originally used only in WPF, some features are dependent on classes that are inside WindowsBase.dll.
Serialize to Xaml with XamlServices
Assuming we have a class called Book, that is defined like this:
public class Book
{
public string Name { get; set; }
public int ISBN { get; set; }
}
In order to serialize it, we use System.Xaml.XamlServices class:
Book book1 = new Book { Name = "First", ISBN = 123 };
string bookFileName = "book.xaml";
using (TextWriter writer = File.CreateText(bookFileName))
{
XamlServices.Save(writer, book1);
}
The output file should contain the following content:
<Book ISBN="123"
Name="My first book"
xmlns="clr-namespace:XamlSamples;assembly=XamlSamples" />
If we have a more complex object graph, for example if each book had a list of related books:
public class Book
{
...
private IList<Book> related = new List<Book>();
public IList<Book> Related { get { return this.related; } }
}
Then for the following books with relations:
Book book1 = new Book { Name = "First", ISBN = 123 };
Book book2 = new Book { Name = "Second", ISBN = 456 };
Book book3 = new Book { Name = "Third", ISBN = 789 };
book1.Related.Add(book2);
book1.Related.Add(book3);
book2.Related.Add(book1);
book3.Related.Add(book1);
The result will be:
<Book x:Name="__ReferenceID0" ISBN="123" Name="First"
xmlns="clr-namespace:XamlSamples;assembly=XamlSamples"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Book.Related>
<Book ISBN="456" Name="Second">
<Book.Related>
<x:Reference>__ReferenceID0</x:Reference>
</Book.Related>
</Book>
<Book ISBN="789" Name="Third">
<Book.Related>
<x:Reference>__ReferenceID0</x:Reference>
</Book.Related>
</Book>
</Book.Related>
</Book>
Notice that the first book is now being identified using the x:Name property and its unique id is __ReferenceID0. This ID is also used to list the related books of the second book. Also note that there is no need to create a unique id to the second book because it is represented as a child element of the first one.
If we wanted to use the Name property of the books as the unique identifier, we could use the System.Windows.Markup.RuntimeNamePropertyAttribute in WindowsBase.dll:
[RuntimeNameProperty("Name")]
public class Book
{
...
}
Now, the output will be:
<Book ISBN="123" Name="First"
xmlns="clr-namespace:XamlSamples;assembly=XamlSamples"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Book.Related>
<Book ISBN="456" Name="Second">
<Book.Related>
<x:Reference>First</x:Reference>
</Book.Related>
</Book>
<Book ISBN="789" Name="Third">
<Book.Related>
<x:Reference>First</x:Reference>
</Book.Related>
</Book>
</Book.Related>
</Book>
Note that there is no x:Name attribute.
If we also want to take out the <Book.Related> nodes, and set its content to be the content node of the Book type, we can use the System.Windows.Markup.ContentPropertyAttribute in WindowsBase.dll.
[RuntimeNameProperty("Name")]
[ContentProperty("Related")]
public class Book
{
...
}
Now, the result is much simpler:
<Book ISBN="123" Name="First"
xmlns="clr-namespace:XamlSamples;assembly=XamlSamples"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Book ISBN="456" Name="Second">
<x:Reference>First</x:Reference>
</Book>
<Book ISBN="789" Name="Third">
<x:Reference>First</x:Reference>
</Book>
</Book>
Deserialize from Xaml with XamlServices
In order to deserialize an object graph from .xaml file, we can use XamlServices.Load method:
using (TextReader reader = File.OpenText(bookFileName))
{
Book book = (Book)XamlServices.Load(reader);
Console.WriteLine("Book {0} (ISBN:{1})", book.Name, book.ISBN);
Console.WriteLine("Related Books:");
foreach (Book relatedBook in book.Related)
{
Console.WriteLine("\t{0} (ISBN:{1})", relatedBook.Name, relatedBook.ISBN);
}
}
After deserialization, the object graph is just as it was before serialization, and the output is:
Summary
In this post I showed basic samples of serialization and deserialization of object graphs uisng XamlServices in System.Xaml as part of the .Net Framework 4.0. In later post I'll talk about some more advanced features such as Attached Properties and more.
.Net RIA Services: Custom Validation
This is another post in a series of posts about building applications with Microsoft .Net RIA Services and Silverlight 3 and ASP.Net.
In my previous post .Net RIA Services Part 3: DataForm and Validation I explained how to add validation metadata to entities and showed how the DataForm control enforces them. I used simple validation metadata attributes such as RegularExpressionAttribute, RequiredAttribute and StringLengthAttribute that help us in basic scenarios.
If you want to write custom validation, you can inherit from System.ComponentModel.DataAnnotations.ValidationAttribute, but a more simple way would be to write a validation method, and share it between the server side and the client side, as I explained in my previous post .Net RIA Services: Sharing Code between the Client and Server.
In CustomerValidation.shared.cs file (in the server side) I wrote the following method, that takes the value of a property and returns an indication whether it is valid or not.
[Shared]
public class CustomerValidation
{
[Shared]
public static bool IsEmailEndsWithDotCom(string email)
{
if (email.EndsWith(".com"))
return true;
return false;
}
}
To apply this validation logic on an entity property, use the CustomValidationAttribute with the about type and method name, and the error message to display.
internal sealed class CustomerMetadata
{
...
[CustomValidation(typeof(CustomerValidation),
"IsEmailEndsWithDotCom",
ErrorMessage = "Customer\'s email address must end with .com")]
public string Email;
...
}
At runtime, the framework will invoke this method passing it the property value, and if it returns False, the error message will be shown.
The above sample is also nice for scenarios is which the logic is independent of any other property about the entity that’s being validated. In cases where you need additional information about the entity to perform the validation logic, you can use a more complex signature of the validation method.
[Shared]
public class CustomerValidation
{
[Shared]
public static bool EnsureBusinessEmailAddress(string email,
ValidationContext ctx,
out ValidationResult result)
{
result = null;
Customer cust = (Customer)ctx.ObjectInstance;
if (cust.IsBusiness)
{
if (!cust.Email.EndsWith(".com"))
{
result = new ValidationResult("Business Customer's email address must end with .com");
}
}
return false;
}
}
In this approach I receive not only the property value, but also an instance of ValidationContext that provides me with some information about the entity and property being validated and also a reference to the entity instance itself.
Using it is the same, except that here I pass the error message in the out parameter ValidationResult, instead of providing it in the validation attribute.
internal sealed class CustomerMetadata {
...
[CustomValidation(typeof(CustomerValidation), "EnsureBusinessEmailAddress")]
public string Email;
...
}
Enjoy!
.Net RIA Services: Sharing Code between the Client and Server
This is another post in a series of posts about building applications with Microsoft .Net RIA Services and Silverlight 3 and ASP.Net.
In this I’ll talk about how to share code between the server side and the Silverlight client application.
One of the great things in .Net RIA Services is that code that we wrote in the server side can be resued in the client side. To do that, create a new class in the server side called with .shared.cs or .shared.vb suffix (CustomerValidation.shared.cs in this sample).

In this class, code what you’d live to share with the client side, under the rational limitations. To make the code sections shared between the server and the client, decorate them with System.Web.Ria.Data.SharedAttribute. For example:
[Shared]
public class CustomerValidation
{
[Shared]
public static bool IsEmailEndsWithDotCom(string email)
{
if (email.EndsWith(".com"))
return true;
return false;
}
}
After you build the solution, Visual Studio will copy this file to the Silverlight client application:
and now, you can use this code in the client application, as you did in the server side. Here is an example of me using the shared code in the HomePage class in the Silverlight client application.
Enjoy!
.Net RIA Services Part 3: DataForm and Validation

This is the forth part in a series of posts about building applications with
Microsoft .Net RIA Services and
Silverlight 3. In
part 1 of this series I created a new application, created a simple data model and used the
Domain Service and
Domain Context to retrieve data and bind it to a
DataGrid. In
part 2 we replaced the manual work needed to get the data from the server with the
DomainDataSource that provided some more advanced scenarios such as filtering and sorting. In this post we’ll introduce the
DataForm control and talk more about data validation.
Using the DataForm control
Add A DataForm Control and bind it to the current item of the DataGrid. Open Views\HomePage.xaml, and add a DataForm Control right after the DataPager.
<Grid x:Name="LayoutRoot" Background="White">
...
<dataControls:DataPager PageSize="3"
Source="{Binding Data, ElementName=customersDataSource}" />
<dataControls:DataForm x:Name="customerDataForm"
Header="Customer Data"
CurrentItem="{Binding ElementName=dataGrid, Path=SelectedItem}">
</dataControls:DataForm>
...
</Grid>
If you run the application, you should see the DataForm below the DataGrid. Move between the items, and see how the displayed customer’s data is changing as you do that.
To edit an item, click the pencil icon on the DataForm.
When you do that, the controls will be replaced with input controls, and Save and Cancel buttons will show up.
If you change a value of a property in a customer’s data, you’ll get a notification that this data was changed and the customer is not “dirty”.
Notice that changes that are made here are tracked only in memory. This means, that by pressing the Save button, you’ll switch over to Display more, but the data is not saved to the server. To enable submitting changes back to the server, we need to add a submit button below the DataForm.
<Button x:Name="btnSubmit"
Width="120"
Click="btnSubmit_Click"
Content="Submit" />
As the implementation of the submit button, you’ll need to commit the changes of the current item that is being edited (similar to EndCurrentEdit() in Windows Forms), and only then pushing the changes back the server.
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
this.customerDataForm.CommitItemEdit();
this.customersDataSource.SubmitChanges();
}
Adding Validation Logic using Data Annotations
One of the great things in .Net RIA Services is that code that we wrote in the server side can be resued in the client side. This means that we can reuse the validation annotations that we have for our domain entities.
To annotate entities with validation semantics, open the metadata file for the domain service (BankDomainService.metadata.cs in the sample). In this file, you’ll find partial classes that match your domain classes (class Customer in this sample), decorated with MetadataTypeAttribute pointing to a metadata type the is also generated here as an inner class. The metadata class has fields / properties that match the properties that the original class has, that you can annotate with validation requirements.
[MetadataTypeAttribute(typeof(Customer.CustomerMetadata))]
public partial class Customer
{
internal sealed class CustomerMetadata
{
public int CustomerID;
public bool IsBusiness;
public string Name;
public string City;
public string Email;
public EntitySet<Account> Accounts;
}
}
In this examples we’ll use the Regular Expression attribute, the String Length Attribute and the Required Attribute to validate the customer entity, but I encourage you to explore the System.ComponentModel.DataAnnotations namespace more deeply.
internal sealed class CustomerMetadata
{
public int CustomerID;
public bool IsBusiness;
[Required(ErrorMessage="Please provide a name for the customer")]
[StringLength(30,
ErrorMessage="Customer's name cannot be more than 30 characters")]
public string Name;
[StringLength(30,
ErrorMessage = "Customer's city cannot be more than 15 characters")]
public string City;
[RegularExpression(@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$",
ErrorMessage="Please provide a valid email address")]
public string Email;
public EntitySet<Account> Accounts;
}
Build the project and Visual Studio will regenerate the client side code for the domain context, that will now also contain the metadata.
If you now run the application, and try to update a customer’s entity with values that do not match the validations, you will get a visual notification and the data will not be updated to the server.
In this post I talked about the new DataForm control in .Net RIA Services, showed how to add it to our application and how it works. Then we talked a little bit about annotating the entities with validation requirements and saw how the DataForm enforces them.
Enjoy!
ASP.Net DomainDataSource with Select Parameters
Continuing with .Net RIA Services with Silverlight and ASP.Net. In the last port I wrote about Using DomainDataSource in ASP.Net, and showed its basic usage. In this post I’ll show a more advanced scenario in which you want to use a domain service select method that takes parameters, and get the parameter value from a control on the form.
In the previous post, we had a GridView bound to a DomainDataSource that called a Select Method on the DomainService.
<asp:GridView runat="server" ID="GridView"
AutoGenerateColumns="true"
DataSourceID="customersDataSource">
</asp:GridView>
<asp:DomainDataSource runat="server" ID="customersDataSource"
DomainServiceTypeName="Samples.Bank.Domain.BankDomainService"
SelectMethod="GetCustomers">
</asp:DomainDataSource>
The output was:

Now we want to filter the output list by the City property. To do that, we first have to add a method in our Domain Service that returns the data filtered by a city parameter.
public class BankDomainService : LinqToSqlDomainService<BankDataContext>
{
public IQueryable<Customer> GetCustomers()
{
return this.Context.Customers;
}
public IQueryable<Customer> GetCustomersByCity(string city)
{
if (city == null)
return GetCustomers();
return GetCustomers().Where(c => c.City == city);
}
...
}
Notice that GetCustomersByCity method uses the GetCustomers method that returns an IQueryable<Customer> and filters the result by city.
To select which city we want to filter by, lets add a ListBox with some items:
<asp:ListBox ID="lstCities" AutoPostBack="true" runat="server">
<asp:ListItem>Tel Aviv</asp:ListItem>
<asp:ListItem>Raanana</asp:ListItem>
<asp:ListItem>Ramat Gan</asp:ListItem>
</asp:ListBox>
Note that I had to specify AutoPostBack=”true” in make any change to the filter, since this is a server control.
Now, in order to filter the data source according to the domain method with the select parameter I have to specify a SelectParameter that takes its value from the ListBox, and change the select method to execute.
<asp:DomainDataSource runat="server" ID="customersDataSource"
DomainServiceTypeName="Samples.Bank.Domain.BankDomainService"
SelectMethod="GetCustomersByCity">
<SelectParameters>
<asp:ControlParameter Name="city" ControlID="lstCities"
PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:DomainDataSource>
Now, If we run the application, we can select items in the ListBox, and the items in the GridView will be filtered by the city value.
Enjoy!