Fixing WCF Circular Reference Serialization

February 3, 2009 14:03 by wjchristenson2

As a WCF developer, you may (or soon will) run into problems when an object is referenced multiple times within the business objects being serialized.  Let’s say we have a parent object which has a collection of children.  Therefore we have one-to-many children for a parent.  Let’s say we want a property for each child which references its parent.  When the DataContractSerializer attempts to serialize the parent and children, you’ll soon discover that the cyclic relationship between the parent and its children and back to the parent will cause a stack overflow.  Below is a basic diagram that shows a basic parent to child – child to parent object (cyclic) relationship where this can occur.

I’ve seen a lot of workarounds to this problem and most involve writing your own serializers.  In .NET 3.5 SP1, we can now specify an IsReference parameter in the DataContract attribute which will automatically retain our cyclic object relationships for us.  Specify this for objects which are referenced in other objects.  In our example, the parent would be a reference because the child object references it.  The child object would not be a reference because the children property is a collection of child.  Simple solution compared to what WCF developers had to do in the past.  Here’s a sample of a class definition that is of a reference type:


   1:      <DataContract(IsReference:=True)> _
   2:      Public Class Parent

Create a Silverlight Message Box

January 31, 2009 12:15 by wjchristenson2

In this post, I’m going to demonstrate the concepts of how to create a simple message box in Silverlight.  We want the message box to be able to do the following:

1.  Center the message box vertically and horizontally on the screen when shown.
2.  When shown, overlay the screen and disable any interaction with controls beneath our message box.
3.  Have a Text property that can be past to the message box programmatically when shown or either via XAML at design time.
4.  The message box should take up 50% of the screen vertically and horizontally when visible.

The requirements above are very basic.  However they should help you get started creating your own message box.  The first thing we’ll do is create our message box control.  We’ll have a rectangle that will function as the overlay behind the message box yet above our work area.  This will fulfill requirement #2.  We’ll also have the UI elements that will be used for the actual message box.  Here’s our control XAML:


   1:  <UserControl x:Class="SilverlightMsgBox.MsgBox"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Visibility="Collapsed">
   4:      <Grid>
   5:          <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" />
   6:          <Border x:Name="brdMsgBox" BorderBrush="Black" BorderThickness="1,1,1,1">
   7:              <Border.Background>
   8:                  <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
   9:                      <GradientStop Color="White"/>
  10:                      <GradientStop Color="Gray" Offset="1"/>
  11:                  </LinearGradientBrush>
  12:              </Border.Background>
  13:   
  14:              <Grid Margin="10,10,10,10">
  15:                  <Grid.ColumnDefinitions>
  16:                      <ColumnDefinition />
  17:                  </Grid.ColumnDefinitions>
  18:                  <Grid.RowDefinitions>
  19:                      <RowDefinition Height="*" />
  20:                      <RowDefinition Height="50" />
  21:                  </Grid.RowDefinitions>
  22:   
  23:                  <TextBlock x:Name="tbkText" Grid.Column="0" Grid.Row="0" Text="Error Text goes here." FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap" />
  24:                  <Button x:Name="btnOk" Content="Ok" Width="100" Height="50" Grid.Column="0" Grid.Row="1" />
  25:              </Grid>
  26:          </Border>
  27:      </Grid>
  28:  </UserControl>

We have a TextBlock for the message and our ok Button which will close the message box once the user reads the message.  Now that our UI elements are defined we create our properties & actions for the control.  Here is the code behind of the MsgBox control:


   1:  Partial Public Class MsgBox
   2:      Inherits UserControl
   3:   
   4:      Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MsgBox), New PropertyMetadata(AddressOf TextChangedHandler))
   5:   
   6:      Public Property Text() As String
   7:          Get
   8:              Return GetValue(MsgBox.TextProperty).ToString()
   9:          End Get
  10:          Set(ByVal value As String)
  11:              SetValue(MsgBox.TextProperty, value)
  12:          End Set
  13:      End Property
  14:   
  15:      Public Sub New()
  16:          InitializeComponent()
  17:      End Sub
  18:   
  19:      Private Shared Sub TextChangedHandler(ByVal o As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
  20:          DirectCast(o, MsgBox).OnTextChanged(args.NewValue.ToString())
  21:      End Sub
  22:   
  23:      Private Sub OnTextChanged(ByVal newText As String)
  24:          Me.tbkText.Text = newText
  25:      End Sub
  26:   
  27:      Private Sub MsgBox_SizeChanged(ByVal sender As Object, ByVal e As System.Windows.SizeChangedEventArgs) Handles Me.SizeChanged
  28:          'message box will be 50% of the width of its parent
  29:          Me.brdMsgBox.Width = Me.ActualWidth * 0.5
  30:          Me.brdMsgBox.Height = Me.ActualHeight * 0.5
  31:      End Sub
  32:   
  33:      Public Sub Show(Optional ByVal text As String = "")
  34:          If Not String.IsNullOrEmpty(text) Then
  35:              Me.Text = text
  36:          End If
  37:          Me.Visibility = Windows.Visibility.Visible
  38:      End Sub
  39:   
  40:      Public Sub Hide()
  41:          Me.Visibility = Windows.Visibility.Collapsed
  42:      End Sub
  43:   
  44:      Private Sub btnOk_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnOk.Click
  45:          Hide()
  46:      End Sub
  47:   
  48:  End Class

We create a Text dependency property so we can set the message box’s text either programmatically or via XAML at design time (requirement #3).  When the text is changed, we set the text property of our text block control.  I also made 2 public functions to either show or hide the message box.  We also define the OK button to hide/close the message box when clicked.  The last functionality of the message box I’d like to discuss is the SizeChanged event.  When the size changes, we want to ensure that our message box only occupies 50% of its parent’s size (requirement #4).

Now we are ready to put our message box control to use.  In this example, I have a textbox and a button.  When I click the button, I read what the user entered into the textbox and show my message box with the entered text.  Here is a screenie of the message box control being put to use.

SilverlightMsgBox_Soln.zip (597.59 kb)


Silverlight Object Disappears if Large Width or Height

January 23, 2009 18:40 by wjchristenson2

After banging my head over this problem for a day, I’ve learned that Silverlight does not support rendering FrameworkElement dimensions larger than Int16.MaxValue (32767).  You may ask why would you ever want object widths or heights larger than 32767?  In most cases, you wouldn’t.  Unfortunately I needed it to and it was a valid business case.  I also have read a few forums where users were trying to view VERY large images or zoom objects and once their dimensions got too large, Silverlight simply couldn’t render them.

I tested this limitation on a few different Silverlight controls and all failed (Rectangle, Canvas, Path, etc).  Next, I tried to draw a line on a canvas which had a start of 0,0 to end of 0,32767.  The line also did not render.  That leads me to think that any object that inherits from FrameworkElement will have this limitation.

I’ve pondered why Microsoft wouldn’t throw an ArgumentOutOfRangeException if it didn’t support such large numbers or even change the Width and Height properties to Int16 instead of a double.  It definitely would have saved me some time.  Happy coding!


Silverlight User Control Inheritance

January 21, 2009 19:09 by wjchristenson2

A lot of Silverlight developers have experience in ASP.NET control development.  If you do, you may have created several ASP.NET server controls that inherit from a base control.  I quickly found myself wanting to perform the same type of functionality in Silverlight, however the solution was not obvious.  In this post, I will show you how to create a base control in Silverlight and inherit from it.

First thing we will do is setup our solution.  I’ve added a Silverlight application, web, and control projects within our solution.  The controls project is a Silverlight class library project.  I made a reference to the controls project in our Silverlight application project.  Here is a screenshot of the solution heirarchy below.

Once our solution is ready, we first need to create our base control and add it to our controls project.  In my example, I created a class called MyBaseControl that inherits from UserControl.  I then proceed to create a method I want my children controls that inherit from it to be able to use.  For our example, I simply made a function which returns the current date & time.


   1:  Option Explicit On
   2:  Option Strict On
   3:   
   4:  Public Class MyBaseControl
   5:      Inherits UserControl
   6:   
   7:      Public Function GetCurrentDateTime() As Date
   8:          Return Date.Now()
   9:      End Function
  10:  End Class

Now that our base control is in place, we can create a new  user control and inherit from MyBaseControl.  Here’s where the meat of this post lies.  We add a New Silverlight User Control to the controls project.  We are going to alter the user control to inherit from our MyBaseControl.  First, we’ll need to alter the XAML that was generated for us.  Instead of opening with <UserControl… we are going to use MyBaseControl.  I open with <local:MyBaseControl… and then I also include our control project’s namespace.


   1:  <local:MyBaseControl 
   2:      x:Class="SLInheritedUserControl.Controls.MyControl"
   3:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   4:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   5:      xmlns:local="clr-namespace:SLInheritedUserControl.Controls">
   6:      <Grid x:Name="LayoutRoot">
   7:          <TextBlock x:Name="tbkCurrentDT" FontSize="14" />
   8:      </Grid>
   9:  </local:MyBaseControl>

Once our XAML is finished, we then need to tell the code behind to inherit from MyBaseControl instead of UserControl.  I also make a call to the GetCurrentDateTime() method which was defined in MyBaseControl and set the text of tbkCurrentDT of MyControl on the Loaded event.  Take a look.


   1:  Partial Public Class MyControl
   2:      Inherits MyBaseControl
   3:   
   4:      Public Sub New 
   5:          InitializeComponent()
   6:      End Sub
   7:   
   8:      Private Sub MyControl_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
   9:          Me.tbkCurrentDT.Text = Me.GetCurrentDateTime().ToString()
  10:      End Sub
  11:  End Class

Simply add the control to your Silverlight’s application root page and you are good to go!  Here’s the XAML of my root page and also a screenshot of the final deliverable.


   1:  <UserControl x:Class="SLInheritedUserControl.Page"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:      xmlns:myctls="clr-namespace:SLInheritedUserControl.Controls;assembly=SLInheritedUserControl.Controls" 
   5:      Width="300" Height="100">
   6:      <Grid x:Name="LayoutRoot" Width="300" Height="100">
   7:          <Grid.Background>
   8:              <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
   9:                  <GradientStop Color="#FF0959F3"/>
  10:                  <GradientStop Color="#FFABC4F5" Offset="1"/>
  11:              </LinearGradientBrush>
  12:          </Grid.Background>
  13:          <myctls:MyControl x:Name="MyControl1" HorizontalAlignment="Center" VerticalAlignment="Center" />
  14:      </Grid>
  15:  </UserControl>

SLInheritedUserControl_Soln.zip (624.20 kb)


Load XAML at Runtime

January 15, 2009 18:19 by wjchristenson2

I've found situations where I want to store XAML in a database or call a PHP or ASP.NET page to generate & return XAML for me.  It's really not that hard to take a XAML string and load it into our Silverlight application.  In this post, I'll show you how to do so.

I'll be using the XamlReader.Load() method to load my XAML into my Silverlight application during runtime.  There are some requirements to using the XamlReader.Load() method.  The XAML string passed to the method must meet the following requirements:

  • The XAML content string must define a single root element.

  • The content string XAML must be well formed XML, as well as being parseable XAML.

  • The required root element must also specify a default XML namespace value. This is typically the Silverlight namespace, http://schemas.microsoft.com/client/2007.

In our example, I have a TextBox which accepts a XAML string.  When I press the "Parse XAML" button, I will use the XamlReader.Load() method to load my XAML and then add the newly created Silverlight object to our Grid.  Here is the XAML that I am going to attempt to parse.  Take note that I've specified the default namespaces.


   1:  <TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Text="TextBlock XAML has been load and added to our Grid!!" />

Once I paste my XAML string into the TextBox and click the "Parse XAML" button, the following code is executed:


   1:  Private Sub btnParse_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnParse.Click
   2:          Me.grdParsedXaml.Children.Clear()
   3:          Me.grdParsedXaml.Children.Add(XamlReader.Load(Me.tbxXaml.Text))
   4:      End Sub

I first clear any existing objects from the parsed XAML grid, then I load the XAML string and add the newly created object to our Grid.

XamlRuntime_Soln.zip (694.55 kb)


Debugging Tips – The remote server returned an error: NotFound

January 14, 2009 09:27 by wjchristenson2

I’ve occasionally run across this error and it can be very frustrating to pinpoint what the actual problem is.  Debugging in Visual Studio does not always give helpful information either.  I’ve spent up to 6 hours on this error before only to find the error to be a simple 2 minute fix.

Steps to Reveal the WCF Service Error:

1) Alter your web.config file where your WCF service behavior is defined to include exception detail in faults.  This will allow us to see the information we need when the WCF service fails.  Visual Studio should give much more helpful exceptions when this is enabled.

2) If you are still having problems, download, install, and run Fiddler.  Fiddler is an HTTP debugging proxy which logs all HTTP traffic between you and the sites you are viewing.  Analyze the traffic/requests to see if anything is abnormal.

3) Run your application and attempt to connect/consume your broke WCF service function.  You should be able to see the failed request in Fiddler.  Once the request that failed is found, inspect the request to view the exception detail message.


Setting DateTime DependencyProperty in XAML

January 9, 2009 10:03 by wjchristenson2

Sometimes when setting properties with XAML you may get the AG_E_PARSER_BAD_PROPERTY_VALUE error.  This can mean a variety of things, but in this post we are going to visit a situation where .NET cannot convert the XAML string to the .NET object's type.

A good example of this is a Date property.  Let's say we have a control that has a MaxDate property.  If we set the property in XAML it may look like this: MaxDate="01-01-2009".  Unfortunately this does not work.  You'll get our fatal parser error because the parser is not smart enough to parse the string to a date type.

The workaround is to hold .NET parsers hand and tell it how to parse the string to our desired type (in this case a Date).  We'll do this by first creating our own TypeConverter.  I'll call it the DateTypeConverter.  We'll inherit from the TypeConverter base class and override key methods used to detect if we can convert from/to a type and handle the actual conversion process.  Here's our TypeConverter class for converting from and to a Date type.


   1:  Imports System.ComponentModel
   2:   
   3:  Public Class DateTypeConverter
   4:      Inherits TypeConverter
   5:   
   6:      Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
   7:          If sourceType.Equals(GetType(String)) Then
   8:              Return True
   9:          Else
  10:              Return MyBase.CanConvertFrom(context, sourceType)
  11:          End If
  12:      End Function
  13:   
  14:      Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
  15:          If destinationType.Equals(GetType(String)) Then
  16:              Return True
  17:          Else
  18:              Return MyBase.CanConvertTo(context, destinationType)
  19:          End If
  20:      End Function
  21:   
  22:      Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
  23:          If TypeOf value Is String Then
  24:              Try
  25:                  Return Date.Parse(value.ToString())
  26:              Catch
  27:                  Throw New InvalidCastException(value)
  28:              End Try
  29:          Else
  30:              Return MyBase.ConvertFrom(context, culture, value)
  31:          End If
  32:      End Function
  33:   
  34:      Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
  35:          If destinationType.Equals(GetType(String)) Then
  36:              Return value.ToString()
  37:          Else
  38:              Return MyBase.ConvertTo(context, culture, value, destinationType)
  39:          End If
  40:      End Function
  41:  End Class

Now that we have our custom converter created, we need to tell our control's property to use this converter when being set via a property attribute.  In our case, when the parser attempts to set the property, it will invoke our DateTypeConverter and parse the string to a date properly.


   1:      Public Shared ReadOnly MaxDateProperty As DependencyProperty = DependencyProperty.Register("MaxDate", GetType(Date), GetType(SilverlightControl1), New PropertyMetadata(Date.MaxValue, AddressOf MaxDateChangedHandler))
   2:   
   3:      <TypeConverter(GetType(DateTypeConverter))> _
   4:      Public Property MaxDate() As Date
   5:          Get
   6:              Return DirectCast(GetValue(SilverlightControl1.MaxDateProperty), Date)
   7:          End Get
   8:          Set(ByVal value As Date)
   9:              SetValue(SilverlightControl1.MaxDateProperty, value)
  10:          End Set
  11:      End Property

Take note of line 3.  Adding the TypeConverter attribute tells the .NET XAML parser to use our DateTypeConverter to parse the String to Date.

SiverlightDateTime_Soln.zip (593.57 kb)


Silverlight Global Properties

January 8, 2009 13:16 by wjchristenson2

It took me awhile to figure out the best way to create objects that can be used application-wide in Silverlight.  I'll quickly show you how easy it is to do so.

Let's say we want a global property that stores when the Silverlight application was first started.  We will acquire the date/time on application startup and store its value in our application object (App.xaml code behind) via a property.  Here's the code to do so in my App.xaml.vb file:


   1:      Private _startDateTime As Date
   2:   
   3:      Public ReadOnly Property StartDateTime() As Date
   4:          Get
   5:              Return _startDateTime
   6:          End Get
   7:      End Property
   8:   
   9:      Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup
  10:          _startDateTime = Date.Now
  11:          Me.RootVisual = New Page()
  12:      End Sub


When my RootVisual (page) loads, I'll get a handle on the current application object and set a TextBlock's text to the applications startup time which is stored in our application's property we defined.  Here's the code to do so:


   1:      Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
   2:          Me.tbkDate.Text = DirectCast(Application.Current, App).StartDateTime.ToShortDateString() & " " & DirectCast(Application.Current, App).StartDateTime.ToShortTimeString()
   3:      End Sub

In line 2, we get a handle on the current application object by casting "Application.Current" to our "App" type.  Once we have this, we can access our newly created property and set our TextBlock's text property to it.

SilverlightGlobal_Soln.zip (583.88 kb)


Silverlight Performance Tips

November 19, 2008 09:30 by wjchristenson2

1)  Do set IsWindowless=False.  There is a high performance price in rendering windowless controls.  However I've found that if you do this, you might run into some problems.  First, if you want your background of your SL application to be transparent, then you must set IsWindowless to True.  Also, if you have HTML overlays (modals) over your SL application, you'll also need to set IsWindowless = True.

2)  Do NOT set the Silverlight's HTML control background property to transparent or any variation thereof (make it opaque).   If the background property is set to such, each render call will go through a blending sequence which adds to a higher CPU cost.

3)  Do change the Silverlight's application default MaxFrameRate.  The default value is 60.  Most SL applications will look/run fine anywhere between 15 to 30.  You can change the MaxFrameRate programmatically or simply markup the Silverlight HTML control.

4)  Do NOT do text size animations.  When you animate the size of text in SL, it uses hinting to smooth each text glyph.  When animating text size, SL may drop frames due to this.  If you can, use a vector graphic to represent large text animations.

5)  Do use Visibility instead of Opacity whenever possible.  Even if an object's opacity is set to 0, SL will still account for it and its still technically rendered.  Setting the object's visibility to Collapsed will cause SL to ignore rendering the object.

6)  When using the MediaElement object, do not specify its Width and Height.  Let SL render the object at its natural size.

7)  Do not set the Width and Height on path objects.  Rely on the points defined for the path.

8)  When displaying a double's value, do use Double.ToString(CultureInfo.InvariantCulture) rather than Double.ToString().  This will alleviate the need for SL to acquire the culture setting before displaying the double and CurltureInfo.InvariantCulture is optimized for perormance.

9)  If your application is very large, consider loading pieces of it "on demand".


Get ActualWidth and ActualHeight in Silverlight

October 17, 2008 12:27 by wjchristenson2

You may often encounter situations where you need to acquire the size of a Silverlight object and the Width, Height, ActualWidth, ActualHeight property values are not set.  This can occur if the Width & Height are set to Auto, if the object being referenced is in the process of being added dynamically, or it can occur in a myriad of other circumstances.

Let's assume that we have a Canvas object as our root element for our Silverlight application.  It's Width and Height are set to Auto.  As its parent is resized, the Canvas object will grow & shrink accordingly.  Now if we want to acquire the Canvas size to do some placement logic of Canvas child elements, we run into our problem.

My first approach was to investigate why ActualWidth and ActualHeight were not telling me (the developer) the ... uh... actual width and actual height.  You'd think the property names would say it all, but they don't.  They actually "get or set the rendered width/height of a FrameworkElement."  Ok, that's easy enough.  We'll just wait until the objects are rendered before we position them.  So, I figured I'd hook into my Silverlight's Loaded event.  At this point all objects should be "loaded" and I can acquire the actual size of my Canvas.  Wrong!  ActualWidth and ActualHeight are calculated based on the Width/Height property values and the layout system.  There is no guarantee as to when these values will be "calculated".  So I've found 2 ways to workaround this issue.

Dispatcher.BeginInvoke()
This approach executes a specified delegate asynchronously on the thread the Dispatcher is associated with.  Measurement and layout passes run in Silverlight asynchronously.  Therefore our ActualWidth and ActualHeight object properties can be set AFTER we actually need them.  Using BeginInvoke() ensures that our ActualWidth and ActualHeight calculations are done as we programmatically access them.  Here is a sample use of .BeginInvoke() and the delegate.


   1:      'ActualWidth and ActualHeight are calculated values and may not be set yet
   2:      'therefore, execute GetLayoutRootActualSize() asynchronously on the thread the Dispatcher is associated with
   3:      Me.Dispatcher.BeginInvoke(AddressOf GetLayoutRootActualSize)
   4:   
   5:      Private Sub GetLayoutRootActualSize()
   6:          Me.tbxInvoke.Text = Me.LayoutRoot.ActualWidth.ToString() & ", " & Me.LayoutRoot.ActualHeight.ToString()
   7:      End Sub

_SizeChanged Event
My preferred method of accessing ActualWidth and ActualHeight in these situations is by hooking into the FrameworkElement's SizeChanged event.  This event is fired when the ActualWidth and ActualHeight values change for a FrameworkElement.  So let's say we have an element which we need to position based on the size of it's parent.  We can hook into the parent's SizeChanged event and position the child element on the fly.  The ActualWidth and ActualHeight properties of the parent would be present at this time.  Here is a snipped of SizeChanged event handling.


   1:      Private Sub LayoutRoot_SizeChanged(ByVal sender As Object, ByVal e As System.Windows.SizeChangedEventArgs) Handles LayoutRoot.SizeChanged
   2:          Me.tbxSizeChanged.Text = Me.LayoutRoot.ActualWidth.ToString() & ", " & Me.LayoutRoot.ActualHeight.ToString()
   3:      End Sub

I've uploaded an example using my 3 tests (page Loaded, BeginInvoke(), and _SizeChanged).  Hope it helps!


ActualWidthHeight_Soln.zip (586.38 kb)