Expressions created in the WF designer are serialized using square brackets, which is shorthand for VisualBasicValue<T> or VisualBasicReference<T>. For example, drop a WriteLine activity into a Workflow, and set its text to the expression


(in VB you can omit the brackets after the ToString). Save your workflow, open it in XAML view (F7 is your friend). You see the following XAML:

<WriteLine Text="[(1 + 2).ToString]" />

Now not all text that you enter into an ExpressionTextBox is serialized in this format. Primitives, strings, TimeSpan, and DateTime are serialized as literals. For example, change the text in your WriteLine to


Save, and view the XAML. You now see the following:

<WriteLine Text="hello" />

In this case, at runtime “hello” is wrapped in a Literal<String> and executed.

So far, so good. You can write all of these types of expressions in the designer, and the ExpressionTextBox will happily display the expression text. This is true even for things like literals of type TimeSpan (in the form 00:11:00), which are not valid Visual Basic expressions. The hostable editor will squiggle things that aren’t valid VB, but you can just ignore the squiggles, and happily serialize the literals, and your workflow will run successfully at runtime.

Now let’s get to the case where you have expressions that were not created in the designer. One scenario for this is when you have a code spitting application that spits out workflows. You can also see this for activities that have default values assigned to its arguments. These workflows can contain expressions like LambdaValue<T> or LambdaReference<T>. When the ExpressionTextBox encounters one of these, it gives up and displays the read only text “Value was set in XAML” in the designer. The workflows can also contain literal expressions of some value type that is not a primitive, string, TimeSpan, or DateTime. For those types of literals, if there is a type converter from the expression type to a string, then the ExpressionTextBox will display the expression text. However, if there is no type converter available, then the text “Value was set in XAML” will be displayed for these literal expressions as well.

Note: there was a breaking change in literal support between Beta 2 and RC/RTM. In beta 2, any type with an available type converter would be serialized as a literal. Now, the runtime only supports literals of value types and strings. This is especially noticeable in the Send activity, which previously used Uris for the EndpointAddress in the format "http://foo". Post beta 2, you have to use new Uri("http://foo").