Want to follow this site? Here's the RSS feed.

Silverlight Label Contents

New Silverlight 3 Features

April 20, 2009

Though I’m a member of the Silverlight 3 Early Adopter’s Program (and thus have been getting weekly builds of Silverlight long before the public beta), I’m probably not going to be writing anything about the new features.  This isn’t because Silverlight 3 is boring, but, rather, because I have a strict policy of never doing something that other’s are already doing.  So, I would like to direct your attention to a few web sites showing the awesome provided by Silverlight 3 (and you won’t find business-application boringness here).

First, Tim Huerer has a nice post giving a very quick rundown of the new features:

Second, Jeff Prosise’s blog shows some of the cooler features of Silverlight 3.  Maybe it’s just because I absolutely HATE business application development, but I find Jeff’s blog to be 100x more interesting than the “how to write use X to write your boring line-of-business application.”  His work is also not for the naive or faint of heart.  Instead, it’s for professional developers (i.e. the extremely rare people who aren’t afraid to do things the right way.)  If Jeff adds more stuff, I’ll add them to this list.

Finally, you can always head over to the Mix ‘09 web site and watch some Silverlight 3 (and 2) videos.  Most of them also have PowerPoint files associated with them.  Personally, I can’t stand the torture of listening to someone take 30 minutes to say something that I can ready in 3 minutes.  That’s one reason I turned Microsoft down when they asked me to turn my Understanding WCF Services in Silverlight 2 into a talk at Mix.  Boring.  Here’s the Mix link:

Jeff Prosise’s Silverlight Tips

April 10, 2009

This post may be completely meaningless to most of the developers out there as it deals with my type of development: non-business application development.  More specifically, Jeff Prosise of Wintellect (the Navy SEALs of .NET) has posted a few really nice tips and tricks for Silverlight development.  These are really great tricks that serve as great examples of some of the more powerful things you can do with Silverlight:

Links

Exception Handlers for Silverlight 2.0

March 31, 2009

Whereas Themelia is my foundation for all .NET development, it’s a little known fact that I have an internal build of it specifically used for Silverlight.  Among the many features of Themelia for Silverlight (hereafter called “ThemeliaSL”) is something I call Exception Handlers.  This isn’t the same thing as the “catch” block of a try/catch.  No, it’s a concept specific to Silverlight.  Also, this is a fairly discrete feature that you can implement in your own Silverlight applications without the need of my full framework.  However, before you can understand this feature, you need to understand Silverlight currently works with unhandled exceptions.

When Silverlight throws an exception that’s unhandled, it eventually gets bubbled up to your System.Windows.Application instance.  If you are handling the UnhandledException event of this class, then you have an opportunity to handle this exception on your own.  When your UnhandledException event handler is called, you are passed an instance of System.Windows.ApplicationUnhandledExceptionEventArgs.  In this class you are provided a property named ExceptionObject of type System.Exception which holds the actual exception object that has been thrown.  There’s one other property though: Handled.  This property is a boolean which provides you with the ability to say whether you handled the exception or not.  If you set this property to true, then you are telling Silverlight that the problem has been taken care of.  If you set it to false, then you are telling Silverlight that it’s about to die.

That’s really all there is to Silverlight exception handling.  You can, however, make things a bit more streamlined.  Say, for example, you know of various types of exceptions that your application or underlying frameworks will throw.  You also know that you want to handle some of them in a specific way.  Or maybe, you just don’t want any communications exceptions to ever be sent back to the client.  For situations like these, you can use the concept I refer to as exception handlers.

Before we implement this concept, lets see how it will be used first:

public class Application : Themelia.Windows.Application
{
    public Application()
        : base()
    {
        AddExceptionHandler(typeof(CommunicationException), delegate(Exception ex)
        {
            if (ex.InnerException == null)
            {

                ReportExceptionToFirebug(ex.InnerException);
                return true;
            }
            //+ 
            return false;
        });
    }
}

Essentially, call the base constructor of the Application class we are about to create.  Then, for each exception that you want to handle, register it with the AddExceptionHandler method, sending it the type of the exception and a delegate of type Func<Exception, Boolean>.  In this example, when an unhandled exception of type CommunicationException is thrown, we automatically check to see if it has an inner exception.  If so, we report the exception in a special way and mark the exception as handled.

You could also add more exception handlers.  Here’s another example:

AddExceptionHandler(typeof(ArgumentException), delegate(Exception ex)
{
    ReportValidationError(ex);
    return true;
});

While this example is a rather silly one (because validation shouldn’t throw exceptions!), it does go to show you this is essentially a declarative model for exception handling.  Now it’s time to move on to build the thing.

First, create your own abstract version of System.Windows.Application.  This is typically a good idea anyways.  It allows you to control your applications in a very streamlined manner.  In this class, add the following static member:

private static Dictionary<Type, Func<Exception, Boolean>> HandlerRegistry = new Dictionary<Type, Func<Exception, Boolean>>();

This represents a registry of all exceptions handlers registered to your application.  It’s a dictionary with the key representing the Type of the exception and the value representing a delegate to be called when that exception is raised.

You’ll also need a standard .NET locking object:

private static Object _lock = new Object(); 

Now add the following method:

//- #AddExceptionHandler -// 
protected void AddExceptionHandler(Type type, Func<Exception, Boolean> handler)
{
    lock (_lock)
    {
        HandlerRegistry.Add(type, handler);
    }
}

This will allow you to register exception handlers from your concrete instance of your custom application class.

Now it’s on to the meat of the implementation.  In your base class application class constructor, handle the UnhandledException event.

this.UnhandledException += new EventHandler<System.Windows.ApplicationUnhandledExceptionEventArgs>(OnUnhandledException);

Then, in the method that will be called upon the event being raised, do something like this:

//- #OnUnhandledException -// 
protected virtual void OnUnhandledException(Object sender, ApplicationUnhandledExceptionEventArgs ea)
{
    lock (_lock)
    {
        if (HandlerRegistry.Count > 0)
        {
            Exception exception = ea.ExceptionObject;
            Type type = exception.GetType();
            if (HandlerRegistry.ContainsKey(type))
            {
                ea.Handled = HandlerRegistry[type](exception);
            }
        }
    }
    if (!System.Diagnostics.Debugger.IsAttached && this.AutoReportErrorToDOM && !ea.Handled)
    {
        ea.Handled = true;
        Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(ea); });
    }
} 

Essentially, if there are any registered handlers, check to see if the currently thrown exception is one of those exception registered to be handled.  If so, then pull the delegate from the registry and call it.

Notice that the delegate that we registered is Func<Exception, Boolean>.  Functionally, this means is that the delegate will accept an Exception object and return a boolean.  Interpreted, this means that in the delegate you register you need to return a boolean representing whether you want the exception handled or not.

You may also notice in the above code that there is a property named AutoReportErrorToDOM.  This does exactly what it says  and it’s nothing too exciting:

//- @AutoReportErrorToDOM -// 
public Boolean AutoReportErrorToDOM { get; set; }

The ReportErrorToDOM method is the same one that Visual Studio 2008 throws in with the Silverlight template.  For completeness, here it is:

//- #ReportErrorToDOM -// 
protected void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs ea)
{
    try
    {
        String errorMsg = ea.ExceptionObject.Message + ea.ExceptionObject.StackTrace;
        errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
        System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight 2 Application " + errorMsg + "\");");
    }
    catch (Exception)
    {
    }
}

At this point, you have everything you need to make the samples that we went through work properly.  Just be sure to base your application class on the new one and you’ll be set.

One important note is that when you are using custom visual entities in Silverlight, you need to make sure that you properly register the namespace in XAML.  For example, say the above class was called “Application” in the “Themelia.Windows” CLR namespace in the “Themelia.Silverlight” assembly.  For this configuration, you would use the following xaml:

<t:Application 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:t="clr-namespace:Themelia.Windows;assembly=Themelia.Silverlight" 
    x:Class="Sample.Application" />

With this, you’re all set.

Tip: Quick Reflector Loading for .NET and Silverlight

March 18, 2009

In my daily development there are three tools that I keep open almost constantly:  Visual Studio 2008, Windows Debugger, and Reflector.  The first is obvious, the second is for extreme-debugging, and the third so I can have a clue what I’m working with (...I have NO idea how people do .NET or Silverlight development without reflector!)  The first two I access with icons, while the third is one that I open and close at least 10 times a day.

To quickly access reflector (as well as Notepad2 and a whole host of sysinternals apps!) I throw it in my Windows folder so I can access it from the Run box.  Not only that, but I typically rename tools I throw in there to have only one letter.  Reflector is “r”.  So, I hit Win-R and type “r”.  Up comes reflector.  Here’s the thing though: I work in both .NET and Silverlight equally.  Yet, Reflector only loads ONE of them.  What to do?

The fix is simple: copy r.exe to rs.exe.  When I load r.exe, I select .NET.  When I load rs.exe, I select Silverlight.  Now I when I hit Win-R, I can type either “r” or “rs” depending on what framework I want to inspect.  You could even take the concept further by making a “rf.exe” for the compact framework”  Each “x.exe” will have it’s own “x.cfg” so the configurations won’t bleed over each other.

Adding XmlNode to Silverlight

February 17, 2009

Of the many types of data I work with, XML shows up all the time.  However, when working in Silverlight, your XML options are dramatically limited.  For example, for some reason Microsoft totally forgot to add a simple XmlNode class.  Microsoft seems to think that using LINQ for XML will solve all our XML problems.  Well, most of the stuff that I do on a daily basis has nothing to do with extensive querying XML.  I just need something simple to pull quick data.  Not only that, but LINQ for XML is in the System.Xml.Linq assembly, which is not a native Silverlight assembly.  I’m not going to bloat my XAP file for a single dependency.

So, in my internal build of Themelia for Silverlight, you will find the Themelia.Xml.XmlNode class.  I use this all over the build entire XML trees and to search the same tree for elements I need.  All this in one small discrete class that doesn’t require you to bloat your XAP file.  Here’s a sample of how to use my XmlNode class:

XmlReader reader = XmlReader.Create(new StringReader(@"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
    <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang=""en-US"">This is the fault reason.</faultstring>
      <detail>
        <FaultDetail xmlns=""http://schemas.datacontract.org/2004/07/Sample.Service"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">
          <Reason>This is the fault reason.</Reason>
          <Source>GetPersonData</Source>
        </FaultDetail>
      </detail>
    </s:Fault>
    </s:Body>
    </s:Envelope>"));
XmlNode node = new XmlNode(reader);
XmlNode faultDetailNode = node.FindDescendant("faultDetail");
stackpanel01.Children.Add(new TextBlock
{
    Text = faultDetailNode.FirstChild.TextContent
});
stackpanel01.Children.Add(new TextBlock
{
    Text = faultDetailNode.AttributeDictionary["xmlns"]
});
stackpanel01.Children.Add(new TextBlock
{
    Text = faultDetailNode.AttributeDictionary["xmlns:i"]
});

It does a few more things that you can see by looking at the source for it, but this is essentially all I need in for XML processing on most days.  Here’s the source for XmlNode.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
//+
namespace Themelia.Xml
{
    public class XmlNode
    {
        //- @Name -//
        public String Name { get; set; }

        //- @TextContent -//
        public String TextContent { get; set; }

        //- @Children -//
        public List<XmlNode> NodeList { get; set; }

        //- @AttributeMap -//
        public Dictionary<String, String> AttributeDictionary { get; set; }

        //- @FirstChild -//
        public XmlNode FirstChild
        {
            get
            {
                if (NodeList.Count > 0)
                {
                    return NodeList[0];
                }
                //+
                return null;
            }
        }

        //+
        //- @Ctor -//
        private XmlNode()
        {
            NodeList = new List<XmlNode>();
            AttributeDictionary = new Dictionary<String, String>();
        }
        public XmlNode(XmlReader xmlReader)
            : this()
        {
            Initialize(xmlReader);
        }
        public XmlNode(Stream xmlStream)
            : this(XmlReader.Create(xmlStream))
        {
        }
        public XmlNode(String name)
            : this()
        {
            Name = name;
        }

        //- $Initialize -//
        private void Initialize(XmlReader reader)
        {
            reader.Read();
            this.Name = reader.Name;
            //+ attribute
            reader.MoveToElement();
            if (reader.HasAttributes)
            {
                reader.MoveToFirstAttribute();
                AttributeDictionary.Add(reader.Name, reader.Value);
                while (reader.MoveToNextAttribute())
                {
                    AttributeDictionary.Add(reader.Name, reader.Value);
                }
            }
            //+ node
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    NodeList.Add(new XmlNode(reader.ReadSubtree()));
                }
                else if (reader.NodeType == XmlNodeType.Text)
                {
                    TextContent = reader.ReadContentAsString();
                }
            }
        }

        //- @FindDescendant -//
        public XmlNode FindDescendant(String name)
        {
            XmlNode foundNode = NodeList.FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
            if (foundNode != null)
            {
                return foundNode;
            }
            foreach (XmlNode node in NodeList)
            {
                foundNode = node.FindDescendant(name);
                if (foundNode != null)
                {
                    return foundNode;
                }
            }
            //+
            return foundNode;
        }

        //- @FindDescendantList -//
        public List<XmlNode> FindDescendantList(String name)
        {
            List<XmlNode> nodeList = new List<XmlNode>();
            XmlNode foundNode = NodeList.FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
            if (foundNode != null)
            {
                nodeList.Add(foundNode);
                foundNode = null;
            }
            foreach (XmlNode node in NodeList)
            {
                foundNode = node.FindDescendant(name);
                if (foundNode != null)
                {
                    nodeList.Add(foundNode);
                    foundNode = null;
                }
            }
            //+
            return nodeList;
        }

        //- @GetChildDictionary -//
        public Dictionary<String, String> GetChildDictionary()
        {
            Dictionary<String, String> map = new Dictionary<String, String>();
            foreach (XmlNode node in NodeList)
            {
                if (!String.IsNullOrEmpty(node.TextContent))
                {
                    map.Add(node.Name, node.TextContent);
                }
            }
            //+
            return map;
        }
    }
}

Yeah, there’s more it could probably do and I’ll probably add more to it in the future, but this little class has worked in all my XML scenarios so far.

Obtaining Enumeration Names and Values in Silverlight 2.0

February 12, 2009

In .NET, when you are dealing with singular enumerations (the ones singular names) or flags enumerations (the ones with plural names), you have the ability to access the names and values of each of the items in the enumeration.  For example, the below code iterates through and prints out both the values and names of the enumeration items:

using System;
//+
namespace Sample
{
    public enum Component
    {
        Keyboard,
        Mouse,
        Display,
        Disk,
        Memory,
        Network
    }

    public class Program
    {
        //- $Main -//
        private static void Main(String[] args)
        {
            //+ name
            foreach (String name in Enum.GetNames(typeof(Component)))
            {
                Console.WriteLine(name);
            }
            //+ value
            foreach (Object value in Enum.GetValues(typeof(Component)))
            {
                Console.WriteLine((Int32)value);
            }
        }
    }
}

Now let’s go to do the same thing in Silverlight 2.0.

image

Err... wait a minute.  Where’s GetNames and GetValues?  Well, they don’t exist.  Fortunately, we have the ability to access these via reflection.  To obtain the names, we just need to obtain the Type object of our enumeration and call GetFields with the Public and Static binding flags set, and look in the resulting FieldInfo array.  Each FieldInfo object will have a Name property without item name.  For the values, we simply use Enum.Parse to turn that name into the actual value.  For the underlying value, we can just cast that to the underlying type of the enumeration.  In the example above, that would be System.Int32.  Here’s all that in action:

 

//- $OnLoaded -//
private void OnLoaded(Object sender, System.Windows.RoutedEventArgs e)
{
    Type enumType = typeof(Component);
    System.Reflection.FieldInfo[] fiArray = enumType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
    foreach (System.Reflection.FieldInfo fi in fiArray)
    {
        //+ name
        sp01.Children.Add(new TextBlock
        {
             Text = fi.Name
        });
    }
    foreach (System.Reflection.FieldInfo fi in fiArray)
    {
        //+ value
        sp01.Children.Add(new TextBlock
        {
            Text = ((Int32)Enum.Parse(enumType, fi.Name, false)).ToString()
        });
    }
}

I’ve left the namespaces of the items in the System.Reflection namespace in place so you can see exactly what types were working with here.

Of course, you can always wrap this up into it’s own class so you can reuse this logic all over:

namespace Themelia
{
    public class EnumReader
    {
        /// <summary>
        /// Gets the names of an enumeration type.
        /// </summary>
        /// <param name="enumerationType">Type of enumeration.</param>
        /// <returns>List of names of the enumeration.</returns>
        public static List<String> GetNameList(Type enumType)
        {
            if (!enumType.IsEnum)
            {
                throw new InvalidOperationException("Specified generic parameter must be an enumeration.");
            }
            List<String> nameList = new List<String>();
            //+ type
            FieldInfo[] fiArray = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
            foreach (FieldInfo fi in fiArray)
            {
                nameList.Add(fi.Name);
            }
            //+
            return nameList;
        }

        //- @GetNameList -//
        /// <summary>
        /// Gets the names of an enumeration type.
        /// </summary>
        /// <typeparam name="T">Type of enumeration.</typeparam>
        /// <returns>List of names of the enumeration.</returns>
        public static List<String> GetNameList<T>() where T : struct
        {
            return GetNameList(typeof(T));
        }

        //- @GetValueList -//
        /// <summary>
        /// Gets the values of an enumeration type.
        /// </summary>
        /// <typeparam name="T">Type of enumeration.</typeparam>
        /// <returns>List of values of the enumeration.</returns>
        public static List<T> GetValueList<T>() where T : struct
        {
            Type enumType = typeof(T);
            if (!enumType.IsEnum)
            {
                throw new InvalidOperationException("Specified generic parameter must be an enumeration.");
            }
            List<T> valueList = new List<T>();
            FieldInfo[] fiArray = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
            foreach (FieldInfo fi in fiArray)
            {
                valueList.Add((T)Enum.Parse(enumType, fi.Name, false));
            }
            //+
            return valueList;
        }
    }
}

In this example class, you can see that two of the methods are actually declared as generic.  So, to use them like this:

//- $OnLoaded -//
private void OnLoaded(Object sender, System.Windows.RoutedEventArgs e)
{
    foreach (String name in EnumReader.GetNameList<Component>())
    {
        //+ name
        sp01.Children.Add(new TextBlock
        {
            Text = name
        });
    }
    foreach (Component component in EnumReader.GetValueList<Component>())
    {
        //+ value
        sp01.Children.Add(new TextBlock
        {
            Text = ((Int32)component).ToString()
        });
    }
}

One thing to keep in mind is that reflection does have a performance hit.  However, given that most of WPF, Silverlight, and WCF are all about constant reflection, you can rest comfortably that it’s not nearly as bad as some people would say.  Having said that, if your application profiling does say that you are reflecting too much, you can always cache the data returned from these method and access the cache instead.  Don’t however, cache for the sake of caching.  Saying “We’re always going to cache, just to be consistent” is as stupid as saying “We’re always going to drive 45mph, just to be consistent.”  This kills people on both the interstate and in school zones.  Make your caching decisions (and ALL other decisions!) based upon your current situation never upon dangerous mindless consistency.

Silverlight Feature Requests

January 21, 2009

Silverlight is probably the most important technology to be released since Firefox 1.0 and that since .NET 1.0.  However, as with most early-edition pieces of software, there are some major things missing.  Below is a list of things that I request that Microsoft add with a quick note on each.  It ranges from a few UI things to the more hardcore mechanical things (...things that many developers will say are meaningless until they learn how to spell C-L-R).

  • GIF Support - Obvious.  It's very odd that some manager somewhere said "no one ever uses GIF anymore".
  • Style Inheritance - Another obvious one.  We who knew WPF long before Silverlight was around THRIVE on this.
  • DockPanel - COME ON! You MUST be joking! I shouldn't have to use a third party CodePlex control for this.
  • VisualBrush - The ability to paint controls on a background and in other places will go a long way in helping people creating more interactive help files and training software.
  • RelativeSource - The ability to bind one element's property to another is EXTREMELY important (i.e. my height == my parent's height).
  • MultiView - It takes almost no code to write this; just make it native so we don't have dozens of versions all over.
  • WebHttpBinding for JSON - POX is less important, but would be nice; JSON is the de facto web standard.
  • System.Security.Cryptography.RSA with providers - This would greatly increase the security of client-server communication.
  • Workflow Foundation - Even a light version with only the basic activities (for, if, while, etc...) would be nice.
  • SVG Viewer - This should shut up the anti-Microsoft cult.
  • Better font rendering - It's HORRIBLE in 2.0.
  • iPhone Support - I think this may take a miracle.
  • MultiTouch - Need this for iPhone support.
  • CSS3 DOM Selector (http://www.w3.org/TR/selectors-api/) - So we use it instead of jQuery's version for closer-to-native speed on EVERY browser without even needing JQuery.
  • A XMLHttpRequest object - This would allow us to use Silverlight's CrossDomainPolicy.xml stuff for cross domain stuff instead of playing games with browser detection nonsense and adding hacks for browsers which don't support it.
  • API for browser abstraction - Web developers HATE having to do lame detection to figure out if we are on IE so we can talk to it like a child.  Give us the ability to create managed extensions to Silverlight so we can add in our pain-in-the-butt browser differences in Silverlight instead of relying on painfully slow JScript rendering and browser detection.
  • Service for extensions - This goes with the last one.  We should have the ability to 1) extend the hardcore functionality of Silverlight and 2) have a centralize service that Silverlight calls to download our functionality when our application requests it.  This would be very just like what Firefox does when it needs a plugin.  It would also do auto-updating like with Firefox extensions.
  • JSON deserializer that actually works to deserialize data serialized by the JSON serializer - JSON is critically important to the web; it should be supported better.
  • The ability to get 500 HTTP status codes from Firefox, Chrome, and IE - This would allow us to use fault contracts in WCF.  This would have to be a pain to implement, though. So, I wouldn't expect it for a while.
  • The ability for NPCTRL to communicate CLR configuration information to the CoreCLR to tweak GC things that are normally in configuration - If the hosting NPCTRL control would just allow us to give it configuration parameters to send to the CoreCLR, that would RULE (like we can already do in .NET with configuration).
  • Hosting documentation that doesn't SUCK - Using Win32/ATL to host a Silverlight control is insane right now.  The documentation is very incomplete and there are NO samples (and the IDL is wrong!)
  • Background GC on Windows - I suspect that this would increase performance in many scenarios.
  • The missing GC methods - The System.GC class is missing a PUBLICLY ACCESSIBLE GetCollectionCount.  This will help us with profiling.  It's marked as internal now and if you try to access it via reflection or other fancy tricks you get security errors.
  • ICorProfilerCallback interface - This is my NUMBER ONE FEATURE REQUEST!  This is REQUIRED to create a Silverlight profiler.  Silverlight will NOT be a technology ready for enterprise usage without this.  PERIOD.
  • Documentation on Silverlight's ETW - it's there and it's working in SL2, but I see absolutely zero docs on how to access it.
  • The native AGCORE and NPCTRL source code - This will aide in performance and feature creation
  • COM interface for hosting the CoreCLR - not really a Silverlight feature, but this would be REALLY nice.

Silverlight SOS Commands

January 03, 2009

Today I became rather curious of what commands Silverlight's version of SOS provided (see my Learning WinDBG/SOS and Advanced Debugging post for more information on SOS).  I didn't really have any guess to whether there would be more, less, or the same.  So I ran Silverlight's SOS.dll through .NET's dumpbin.exe application with the /exports switch to get a list of what you can do with it.  In this case, the lower case DLL exports are the actual SOS commands you can use.  I did dumpbin.exe on the .NET 2.0 version and did a diff between them.  The results?  The Silverlight version of SOS actually has more commands than the .NET version.

Here is a list of SOS commands that aren't in the .NET version:

analyzeoom histobj vh
ao histobjfind vo
dumpsigelem histroot  
findroots histstats  
fq hof  
gcheapstat listnearobj  
gcwhere lno  
heapstat t  
histclear tp  
histinit verifyobj  

You can type these into your debugger to see the specific syntax for each of these.  For detailed information on most of these, you'll have to wait until something gets posted on MSDN or one of the SOS developers post something.  For a few, however, Sasha Goldshtein has provided some information and examples.  Here are some posts from this person's web site where you can find information no some of these new commands:

In case you're wondering, the .NET version has a few commands that the Silverlight version didn't have too.  This isn't a big deal as the commands that are missing don't really have much meaning for Silverlight (or have an alternative).  Here's a list of these:

comstate
dumpmethodsig
rcwcleanuplist
tst

Also, for the sake of completeness, below is the completely list of all Silverlight commands.  Just type then into WinDBG with the ! prefix to play with each of them.  For many of them you can type "!sos.help COMMANDNAME" to get help for a specific COMMANDNAME.

analyzeoom dumpsigelem histclear syncblk
ao dumpstack histinit t
bpmd dumpstackobjects histobj threadpool
clrstack dumpvc histobjfind threads
da eeheap histroot token2ee
do eestack histstats tp
dso eeversion hof traverseheap
dumparray ehinfo ip2md u
dumpassembly finalizequeue listnearobj verifyheap
dumpclass findappdomain lno verifyobj
dumpdomain findroots minidumpmode vh
dumpheap fq name2ee vmmap
dumpil gchandleleaks objsize vmstat
dumplog gchandles pe vo
dumpmd gcheapstat printexception  
dumpmodule gcinfo procinfo  
dumpmt gcroot savemodule  
dumpobj gcwhere soe  
dumpruntimetypes heapstat sosflush  
dumpsig help stoponexception  

Then there's the complete list of .NET SOS commands:

bpmd dumpstack procinfo
clrstack dumpstackobjects rcwcleanuplist
comstate dumpvc savemodule
da eeheap soe
do eestack sosflush
dso eeversion stoponexception
dumparray ehinfo syncblk
dumpassembly finalizequeue threadpool
dumpclass findappdomain threads
dumpdomain gchandleleaks token2ee
dumpheap gchandles traverseheap
dumpil gcinfo tst
dumplog gcroot u
dumpmd help verifyheap
dumpmethodsig ip2md vmmap
dumpmodule minidumpmode vmstat
dumpmt name2ee  
dumpobj objsize  
dumpruntimetypes pe  
dumpsig printexception  

If you haven't noticed yet, most of these aren't even documented commands. However, if you type them into SOS, you will not only see that they exist, you will be given the syntax for how to use them (and, then, there's !sos.help).

kick it on DotNetKicks.com

Learning WinDBG/SOS and Advanced Debugging

January 02, 2009

In my daily R&D work as well as in my general development, I always keep WinDBG open so I can quickly debug major problems in a system or just to take a look under the covers. WinDBG is short for Windows Debugger and it's what you would use if you were to debug a Windows driver or figure out why your system blue screened.  It's an advanced unmanaged debugger.  If you're into internals and eat up books like Windows Internals and Windows via C/C++, then you will or probably already do love Windows Debugger.

You can use it for more than unmanaged debugging though.  The .NET framework ships with a product called SOS, which you can load into WinDBG to enable advanced managed debugging.  Actually, with the proper settings ("Enable unmanaged code debugging" to true) you can sometimes load SOS in Visual Studio.  Using either, you can do anything from break when a particular method is called, dump out the IL at a particular place in your call stack (yes, this means you can view the code at runtime without needing the code!), view the methods of a type, or even break when the CLR first loads.  It's incredibly powerful.  You don't even need to be at the system to use it.  Just have someone send you a memory dump and you can use that just as easily as if you were physically at the system.

You can even use it to debug .NET applications inside of unmanaged applications.  For example, WinDBG is the tool I used to figure out why Visual Studio 2008 didn't allow .NET assemblies to be referenced in Silverlight.  Visual Studio was simply loading a managed assembly to do all of its assembly reference dirty work.  Since .NET has this awesome thing called the CTS (Common Type System), types are actual types instead of just chunks of memory.  So when you pause a process and walk through memory, you don't just see memory addresses like 0x018271927, but you see things like System.String with a value of "ctl02".

In addition to being able to debug unmanaged code, .NET code, and .NET code in unmanaged code, you can also use WinDBG to debug Silverlight code.  As it turns out, when you install Silverlight, sos.dll is installed in your %ProgramFiles%\Microsoft Silverlight\2.0.31005.0\sos.dll folder (or on a 64-bit system, %ProgramFiles(x86)%\Microsoft Silverlight\2.0.31005.0\sos.dll).  Just attach your debugger to the unmanaged browser to debug the managed Silverlight application.

At this point you might expect me to announce that I'm going to do some long series on how to effectively use SOS, but that's not the case for two reasons: first, I'm not going to dump out a series of screen shots when many others have done this already.  Second, 90%+ of advanced debugging is all about understanding internals; something that takes many hours of study over many months.  Don't think that learning some tool will help you to effectively debug serious problems.

Thus, remember this: your ability to debug something is directly proportional to your knowledge of the system.  As I say regularly, if you ever try to fix something without understanding it, you are, at best, doing little more than hacking.  Therefore, instead of writing a series, I'm going to refer you to a series of places where you can easily learn all about WinDBG and, more importantly, advanced debugging and system internals.

Before you go diving into a list of resources, though, you need to realize that WinDBG, like Visual Studio's built-in, toned-down debugger, is only a tool.  As I've already mentioned, no tool will ever replace the need for the human to know how to use the tool or how to interpret the information provided by the tool.  Knowledge of debugging is required before you can use a debugging tool effectively.  Logic is also always required when debugging any issue.  Not only that, but as previously mentioned, deep knowledge of the internals of the system you are debugging is non-negotiable.  If you don't know what a MethodDesc, what a method table, or even what a module is, then your debugging abilities will be severely limited.  You won't have a clue how to find or interpret your debug output.

The more you know about the CLR, memory management, threading, garbage collection, the CLR's type system, and Windows the better off you are.  If you understand why .NET finalizers should only be used once every 10 years, you're on the right track.  If you don't even know how many generations are in .NET's garbage collector, you have some serious research ahead of you.  The more you know, the better off you are.  This applies to the whole of the system.  I hear people all the time talking about the "stack" and the "heap" as if they are some ethereal concept beyond human grasp.  These people typically have no idea that these are concepts that predate .NET by decades.  If you can't explain the stack and heap from a C/C++ perspective, then you don't truly understand the concepts.

Also, if you understand memory management in C/C++, you're way ahead of the game.  Even though you don't normally see them in a typical ASP.NET web form, you should know your pointers as they are the foundation of all memory management.  Without awareness of pointers, the entire concept of "passing by reference" is little more than magic.  You need to know why something is a value type and why something is a reference type.  If you don't understand the concept of a sync block index, then you're always wonder why you can't lock on a value type and why you can lock on a value type cast to an interface.  This type of information will go a long way to help you not only debug a system, but, equally important, to make sure it has optimal performance.

You should also not be afraid of IL.  This is the language of .NET.  You don't need to care about becoming fluent in writing in IL.  I promise you that you won't be required by any fascist employer to write a full-scale WPF system in IL.  However, if you don't even know what boxing, you need to hit the books.  Knowledge of IL dramatically aides in your understanding of both the framework class library and the CLR.  You should be aware of what is actually happening under the covers.  Don't simply assume that the csc.exe or vbc.exe compilers will fix your coding flaws.  Some times the code created by these compilers isn't optimal.  You should also understand what the evaluation stack is and how stack-based programming works as this is the foundation for IL development.

Fortunately, there are resources for these prerequisites of advanced debugging in addition to the following debugging resources.  Not only that, but there's two books that explains just about every thing I've just mentioned!  It's Jeffery Richter's CLR via C# and Joe Duffy's .NET Framework 2.0.  Buy these books and a stack of highlighters and study until every page has marks, notes, and coffee stains on them.  In addition to this, you should probably also drop by your local book store, grab a book on C/C++ and read a chapter or two on memory management so you can see the types of things the CLR has to deal with so you don't have to.

For even deeper debugging, though, you may want to study the "Processor Architecture" section of the WinDBG help files, get the aforementioned Windows/C++ books, and buy Advanced Windows Debugging as well.  Everything you study is just "code", so the more you know, the deeper you can debug.  Not just debugging though, but knowledge of internals help you get more knowledge of internals.  By understanding C++, assembly language, and Windows internals, you already have just about everything you need to do effective reverse engineering.  This will help you to understand the undocumented internals and features of various technologies.

These things will help further your knowledge of what's actually going on in .NET's brain.  It's also important to remember that you won't learns this stuff over night.  As I said, your debugging skills are directly related to your knowledge of internals.  Therefore, as pick up more prerequisites in your career, you will become better at debugging (and performance optimization).  Every few months I take some time to further my understanding of the internals of new (and even sometimes old) technologies for these specific reasons.  For example, in Q1 and Q2 of 2009, I'm spending the bulk of my time studying assembly language and Windows architecture to further my own understanding.

Now on to the resources (which will be updated every now and again):

Advanced Debugging Resources

Reusing .NET Assemblies in Silverlight

December 20, 2008

Table of Contents

Introduction

Long before Silverlight 1.0 was released, it was actually called WPF/E or WPF Everywhere.  The idea was to allow you to create WPF like interfaces in your web browser.  This can be seen in a very small way in Silverlight 1.0.  All it provided was very basic primitive objects with the ability for interact with client-side technologies like JavaScript.  However, with Silverlight 2.0, Silverlight is actually more than what was originally promised with the term "WPF/E".  Silverlight is now far much more than a graphical technology.  All this stuff about Silverlight being "WPF for the Web" is more to make the marketing folks happy than anything else.

As a technology parallel to .NET, Silverlight is not part of the .NET family.  Rather, it essentially mirrors the .NET platform to create a new platform inside of a web browser where you have a mini-CLR and mini-Framework Class Library (FCL).  However, even though they are parallel technologies, you would suspect that Microsoft would allow some level of reuse between the two.  As it turns out, most topics are completely reusable.  Among other things, Silverlight has delegates, reference types, value types, a System namespace, and the ability to write code in both C# and VB.

Furthermore, despite the rumors, Silverlight also shares the exact same module and assembly format as .NET.  This may seem completely shocking to some people given the fact that Visual Studio 2008 doesn't allow you to reference a .NET assembly in a Silverlight project.  In reality, however, there's no technical reason for this prohibition.  There isn't a single byte difference between a Silverlight and .NET assembly.  One way to see this is by referencing a Silverlight assembly in a .NET project.  Just try it.  It works great.  So, why doesn't Visual Studio allow .NET assemblies in Silverlight projects?

To answer this, we need to understand that just because an optional helper tool (i.e. Visual Studio) doesn't allow something, that doesn't mean the technology itself doesn't.  In this case, the reason why Visual Studio allows a .NET project to reference Silverlight assemblies, but not the other way around is probably because .NET assemblies can normally do more.  For example, .NET has all kinds of XML related entities in its System.Xml assembly.  If Silverlight were to try to use this, it would blow up at runtime.  However, both Silverlight and .NET have an mscorlib assembly thus giving them a sense of brotherhood.  Having said that, Silverlight has the System.Windows.Browser assembly which, upon access in .NET, would make your .NET application explode!  Thus, the Visual Studio restriction laws are flawed.

Fortunately, there are ways around Visual Studio's fascist regime.  I'm going to talk about two different ways of reusing .NET assemblies and code in Silverlight.  The first technique is the more powerful assembly-level technique, while the second is more flexible file-level technique.  Each technique is useful for its own particular scenarios.  Please keep naive comments of "I'm ALWAYS going to..." and "I'm NEVER going to..." to yourself.  You need to make decisions of which of these techniques or possibly another technique to use on a case by case basis.

The Assembly-Level Technique

For this technique, you need to understand what's going on under the covers when you try to add a .NET reference to your Silverlight application in Visual Studio.  It's actually incredibly simple.  Visual Studio isn't a monolith that controls all your code from a centralized location; sometimes it uses plug-ins to do it's dirty work.

In this case, Visual Studio 2008 uses the Microsoft.VisualStudio.Silverlight .NET assembly.  In this assembly is the Microsoft.VisualStudio.Silverlight.SLUtil class which contains the IsSilverlightAssembly method.  When you add an assembly to a Silverlight Project, this method is called internally to see if your assembly is Silverlight.  If it is, it will add it.  If not, it won't.  It's just that simple.  But, given that the Silverlight and .NET assembly format is the same, how can it know?

You may be shocked to find out that the reason behind this is completely artificial: if the assembly references the 2.0.5.X version of the mscorlib assembly, then Visual Studio says that it's a Silverlight assembly!  This test is essentially all the IsSilverlightAssembly does.  Therefore, if you take your .NET 2.x/3.x assembly and change the version of mscorlib that your assembly references from 2.0.0.0 to 2.0.5.0, you may then add the assembly as a reference.  Now let's talk about this with a more hands on approach.

Below is the sample code we will be working with for this part of the discussion.  Say this code is placed in an empty .NET project.  When it is compiled, we will have an assembly.  Let's call it DotNet.dll.

using System;
//+
namespace DotNet
{
    public class Test
    {
        public String GetText()
        {
            return String.Format("{0} {1} {2} {3}", "This", "is", "a", "test");
        }
    }
}

Before we go any further, lets' discuss the state of the universe at this point.  If you ever try to solve a problem without understanding how the system works, you will at best be hacking the system.  Professionals don't do this.   Therefore, let's try to understand what's going on. 

The first thing you need to know is that when you add an assembly to a project in Visual Studio, you are simply telling Visual Studio to tell the compiler what reference you have so that when the compiler translates your code into IL, it knows what assemblies to include as "extern assembly" sections.  Even then, only the assemblies that are actually used in your code will have "extern assembly" sections.  Thus, even if you added reference every single assembly in your entire system but only use two, the IL will only have two extern sections (i.e. references assemblies).  The second thing you need to know is that no matter what, your assemblies will always have a reference to mscorlib.  This is the root of all things and is where System.Object is stored.

To help you understand this, let's take a look at the IL produced by this class.  To look at this IL, we are going to use .NET's ILDasm utility.  Reflector will not be your tool of choice here.  Reflector is awesome for referencing code, but not for working with it.  It's more about form than function.  With ILDasm we are going to run the below command:

ILDasm DotNet.dll /out:DotNet.il

For the sake of your sanity, use the Visual Studio command prompt for this.  Otherwise you will need to either state the absolute path of ILDasm or set the path.

This command will produce two files: DotNet.il and DotNet.res.  The res file is completely meaningless for our discussion and, therefore, will be ignored.  Here is the IL code in DotNet.il:

.assembly extern mscorlib
{
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
    .ver 2:0:0:0
}
.assembly DotNet
{
    /** a lot of assembly level attributes have been left out **/

    .hash algorithm 0x00008004
    .ver 1:0:0:0
}
.module DotNet.dll
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 
.corflags 0x00000001     

.class public auto ansi beforefieldinit DotNet.Test extends [mscorlib]System.Object
{
    .method public hidebysig instance string GetText() cil managed
    {
        .maxstack    4
        .locals init ([0] object[] CS$0$0000)
        IL_0000:    ldstr "{0} {1} {2} {3}"
        IL_0005:    ldc.i4.4
        IL_0006:    newarr [mscorlib]System.Object
        IL_000b:    stloc.0
        IL_000c:    ldloc.0
        IL_000d:    ldc.i4.0
        IL_000e:    ldstr "This"
        IL_0013:    stelem.ref
        IL_0014:    ldloc.0
        IL_0015:    ldc.i4.1
        IL_0016:    ldstr "is"
        IL_001b:    stelem.ref
        IL_001c:    ldloc.0
        IL_001d:    ldc.i4.2
        IL_001e:    ldstr "a"
        IL_0023:    stelem.ref
        IL_0024:    ldloc.0
        IL_0025:    ldc.i4.3
        IL_0026:    ldstr "test"
        IL_002b:    stelem.ref
        IL_002c:    ldloc.0
        IL_002d:    call  string [mscorlib]System.String::Format(string, object[])
        IL_0032:    ret
    }

    .method public hidebysig specialname rtspecialname 
         instance void    .ctor() cil managed
    {
        .maxstack    8
        IL_0000:    ldarg.0
        IL_0001:    call  instance void [mscorlib]System.Object::.ctor()
        IL_0006:    ret
    }
}

Right now we only care about the first section:

.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}

This ".assembly extern ASSEMBLYNAME" pattern is how your assembly references are stored in your assembly.  In this case, you can see that mscorlib is referenced using both it's version and it's public key.  For our current mission, all we need to do is change the second 0 to a 5.  The public key tokens used in Silverlight are completely different from the ones in .NET, but we are trying to fool Visual Studio, not Silverlight.  This is a compile-time issue, not a runtime-issue.  Speaking more technically, we don't care about the public key token because this information is only used when an assembly is to be loaded.  The correct mscorlib assembly will have already loaded by the Silverlight application itself long before our assembly comes on the scene.  So, in our case, this entire mscorlib reference is really just to make the assembly legal and to fool Visual Studio.

Once you make the change from 2:0:0:0 to 2:0:5:0, all you need to do is use ILAsm to restore the state of the universe (unlike Reflector with C#, ILAsm can put humpty dumpty back together again).  Here's our command for doing this (in this case the resource part is completely optional, but let's add it for completeness):

ilasm DotNet.il /dll /resource:DotNet.res /out:DotNet2.dll

You are now free to reference your .NET assembly in your Silverlight project or application.  As I've already mentioned, Silverlight and .NET have the same assembly format.  There's nothing in Silverlight that stops us from referencing .NET assemblies, it was only Visual Studio stopping us.

At this point you have just the basics of this topic.  However, it's not the end of the story.  As you should be aware, .NET's core assemblies use four-part names.  That is, they have a strong name.  This is used to disambiguate them from other assemblies.  That is, instead of the System assembly being called merely "System", which can easily conflict with other assemblies (obviously written by non-.NET developers who don't realize that System should be reserved), it's actually named "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".  When you reference an assembly, you need to make sure to match the name, version, culture, and public key token.  When it comes to using .NET assemblies in Silverlight, this is critically important.

Let's say, for instance, that you created a .NET project which referenced and used entities from the System, System.ServiceModel, and System.Runtime.Serialization assemblies.  In this case, the IL produced by the .NET compiler will create the following three extern assembly sections:

.assembly extern System
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 2:0:0:0
}
.assembly extern System.ServiceModel
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 3:0:0:0
}
.assembly extern System.Runtime.Serialization
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 3:0:0:0
}

Notice the public key token on each.  Here all three are the same, but for other .NET assemblies they may be different.  What's important here, though, is that the keys are used to identity the assemblies for .NET, not Silverlight.  Thus, even though you did add your .NET assembly to your Silverlight application, an exception would be thrown in runtime at the point where your application tries to access something in one of these assemblies.

The following shows you what would happen in the extreme case of trying to use the System.Web assembly in your Silverlight.  You would get the same error if you tried to access something in one of the above assemblies as well.

AssemblyException

As it stands, though, we can fix this just as easily as we fixed the mscorlib problem in Visual Studio.  All we need to do is open our IL and change the public keys and versions to the Silverlight versions.  Below is a list of the common Silverlight assemblies each with their public key token and version:

.assembly extern mscorlib
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Core
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Net
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Runtime.Serialization
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Windows
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Windows.Browser
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}

//+ note the different public key token in the following
.assembly extern System.ServiceModel
{
  .publickeytoken = (31 BF 38 56 AD 36 4E 35)
  .ver 2:0:5:0
}
.assembly extern System.Json
{
  .publickeytoken = (31 BF 38 56 AD 36 4E 35)
  .ver 2:0:5:0
}

Just use the same ILDasm/Edit/ILAsm procedure already mentioned to tell the assembly to use the appropriate Silverlight assemblies instead of the .NET assemblies.  This is an extremely simple procedure consisting of nothing more than a replace, a procedure that could easily be automated with very minimal effort.  It shouldn't take you much time at all to write a simple .NET application to do this for you.  It would just be a simple .NET to Silverlight converter and validator (to test for assemblies not supported in Silverlight).  Put that application in your Post Build Events (one of the top 5 greatest features of Visual Studio!) and you're done.  No special binary hex value searching necessary.  All you're doing is changing two well documented settings (the public key token and version).

For certain assemblies, this isn't the end of the story.  If your .NET assembly has a strong name, then by modifying it's IL, you have effectively rendered it useless.  Aside from disambiguation, strong names are also used for tamper protection.  You can sort of think of them as a CRC32 in this sense.  If you were to modify the IL of an assembly with a strong name, you would get a compile-time error like the following:

StrongNameException 

However, as you know by the fact that we have looked at the raw text of the source code with our own eyes, the strong name does absolutely no encryption of the IL.  That's one of the most common misconceptions of strong names.  They are not used as for public key encryption of the assembly.  Therefore, we are able to get around this by removing the public key from our assembly before using ILAsm.  Below is what the public key will look like in your IL file.  Just delete this section and run ILAsm.

.publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00
              00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00
              37 3C 5A 7F 6D B6 3F 30 D8 3F DE E3 17 FE E5 2E
              68 43 16 A9 7C 42 69 5A 05 52 E6 73 C5 AC 58 7E
              B0 00 9F DC 1B 0A 78 57 79 12 79 53 E1 60 EB C9
              ED 49 7C 8C 73 1B 01 A7 BA 57 79 B5 53 83 8B CA
              8D F8 6F 3B BD A5 E4 BA 6A 12 B9 52 F2 E9 A3 FC
              42 17 E4 33 97 92 DC 21 30 57 B9 D3 63 7A F2 43
              73 42 70 18 89 8B 44 B9 D4 5A BA A9 21 A3 D9 E0
              86 20 3C 30 01 A9 B9 BB F4 D8 79 B7 7D 56 5A A9)

Upon using ILAsm to create the binary version of the same IL, you will be able to add your assembly, compile and run your application without a problem.  However, you can take this one step further by telling ILAsm to sign the assembly using your original strong name key.  To do this, just use the key command line option to specify the strong name key you would like to use.  Below is the new syntax for re-signing your assembly:

ILAsm DotNet.il /dll /resource:DotNet.res /out:DotNet11.dll /key=..\..\MyStrongNameKey.snk

At this point you have a strongly-named Silverlight assembly createdrom your existing .NET assembly.

Now, before moving on to explain a more flexible method of reuse, I want to cover a few miscellaneous topics.  First, for those of you who know some IL and are trying to be clever to make this process even simpler, you may think you could just do the following:

.assembly extern mscorlib { auto }

This won't work as ILAsm will look for "auto" and place the 2.0.0.0 version in it's place, thus leaving you right where you started.  Also, don't even think about leaving the entire mscorlib part off either.  That won't fool anyone since ILAsm will detect that it's missing and add it before continuing the assembly process.  You need to explicitly state that you want assembly version 2.0.5.0.

Second, you need to think twice before you add a Silverlight assembly to a .NET application.  In the Visual Studio world, if you add a .NET assembly, you add only that assembly. But, in the that assembly is a Silverlgiht assembly, then you will see all of the associated Silverlight assemblies added for each culture you have.  When I did this on my system, exactly 100 extra files were added to my Bin folder!  That's insane.  So, perhaps the Visual Studio team put a "Add Reference" block in the wrong place!

The File-Level Technique

Now all of this is great.  You can easily access your .NET assemblies in Silverlight.  But, many times this isn't even what you need.  You need to remember that every time you reference an assembly in Silverlight, you increase the size of your Silverlight XAP package.  Whereas .NET and Silverlight will only register assembly references in IL when they are actually used, Silverlight will package referenced assemblies in the XAP file regardless of use.  They assemblies will also be registered in the AppManifest.xaml file as an assembly part.  Though the XAP file is nothing more than a ZIP file, thereby shrinking the size of the assembly, this still spells "bloat" if all you need is just a few basic types from an assembly that's within your control.  For situations like this, there's a much simpler and much more flexible solution.

The solution to this again deals with understanding the internals of your system: whenever you add a file to your project in Visual Studio, all you are really doing is adding a file to an ItemGroup XML section in the .NET project file.  This is just a basic text file that describes the project.  As you may have guessed, the ItemGroup section simply contains groups of items.  In the case of compilation files (i.e. classes, structs, enums, etc...), they are Compile items.  Here's an example of a snippet from a .NET project:

<ItemGroup>
  <Compile Include="Client\PersonClient.cs" />
  <Compile Include="Agent\PersonAgent.cs" />
  <Compile Include="Properties\AssemblyInfo.cs" />
  <Compile Include="Configuration.cs" />
  <Compile Include="Information.cs" />
  <Compile Include="_DataContract\Person.cs" />
  <Compile Include="_ServiceContract\IPersonService.cs" />
</ItemGroup>

Given this information, all you need to do is (1) create a Silverlight version of this assembly, (2) open the project file and (3) copy/paste in the parts you want to use in your Silverlight project with the appropriate relative paths changed.  This will create a link from the Silverlight project's items to the physical items.  No copying is done.  They are pointing to the exact same file.  When they are compiled, there is no need to do any IL changes in your assemblies at all since the Silverlight assembly will be Silverlight and the .NET assembly will be .NET.

Now that you know about this under-the-covers approach, you should be aware that this is actually a fully supported option in Visual Studio.  Just go to add an existing item to your project and instead of clicking add or just hitting enter, hit the little arrow next to add and select "Add As Link".  This will do the exact same thing as what we did in our bulk copy/paste method in the project file.  Here's a screen shot of the option in Visual Studio:

AddAsLink

What may be more interesting to you is that this feature may be used anywhere in .NET.  You can use this to reuse any files in your entire system.  It's a very powerful technique to reuse specific items in assemblies.  It comes it very handy when two assemblies need to share classes and creating a third assembly which both may access leads to needless complexity.

Conclusion

Given these two techniques, you should be able to effectively architect a solution that scales to virtually any number of developers.  The first technique is easy to deploy using a custom utility and post build events, while the second is natively supported by any good version control systems.  Keep in mind though, that when using the first technique you may not always need to do this on every build.  The best approach I've seen for this is to have a centralized location on a network share that contains nightly (or whatever) builds of core assemblies.  Then, a login script will copy each of the assemblies to each developers machine.  This will cut down on the complexity of compilation and dramatically lower the time to compile any solution.

Regardless of which technique you use, you should feel a sense of freedom knowing of their existence.  This is especially true if all you are doing is trying to share data contracts between .NET and Silverlight.  As I've mentioned in my popular 70+ page "Understanding WCF in Silverlight 2" document, the "Add Service Reference" feature is not something that should be used in production.  In fact, it's painful in development as well.  Using the techniques described here, you can easily share your data contracts between your .NET server and the Silverlight client without the FrontPage/Word 95 style code generation.  For more information on this specific topics, see the aforementioned document.

Links

kick it on DotNetKicks.com

FREE Silverlight Training on the Web

December 16, 2008

In case you didn't know it, knowledge is free.  In fact, it always has been.  Some cultures make it hard to obtain, but it's free nonetheless.  The Internet gives you extremely close access this knowledge.  You can randomly choose just about any topic in the world and find at least one article, blog posting, or Wikipedia entry on the topic.  In fact, when I was in college I only showed up once to my Kansas State University Physics II class.  Instead I kepted up with the class from home by watching the MIT OpenCourseWare video courses.  When it comes to Internet-related technologies like Silverlight, knowledge is even easier to find.

I see all kinds of courses by some of the biggest training companies offering all sort of great Silverlight courses.  However, these are extremely pricey.  There are also many books on Silverlight coming out.  Again, not free.  But think about it, how do you think the trainers and authors get their information?  When I was offered my Silverlight 2 book deal (since being on a deadline sucks, I turned it down), where do you think I would get my information?  It's all free online.  Here in December 2008, there are all kinds of amazing free resource for learning Silverlight.  You do not need training.  You do not need to buy a book.  Here are some of these resources that I've found this year to help bring you from ground zero to being a Silverlight master:

First, there's the 53-part video series at Silverlight.net.  This series just about every single topic you will ever see in your Silverlight career.  However, I would consider these to be at the basic level.  They cover the fundamentals of each topic, give great tips, and progressively give more interesting examples as the videos progress.  If all you are going to be doing is under-using Silverlight 2 as an RIA platform and for general [boring] UI development, then this series may be 90% of what you need.  Link: http://silverlight.net/Learn/videocat.aspx?cat=2

Second, there's the 44-part video series from Mike Taulty.  This is the guy behind the MSDN Nuggets videos.  These videos are more at the intermediate-advanced level.  It's also somewhat focused at "under-the-covers" development.  Mike doesn't do drag-n-drop videos.  He teaches real technology.  Whereas the previous series will discuss concepts and how to do things "out of the box", Mike's videos show you how to work with things at a more mechanical level, thus giving you a much greater level of control.  If you don't know the topics he's discussing in the videos, you don't know Silverlight.  Link: http://channel9.msdn.com/posts/Dan/Mike-Taulty-44-Silverlight-20-Screencasts/

Third, let's not forget that Microsoft has its annual Mix and PDC conferences.  Microsoft makes sure that the content for these conferences are freely available online.  The Mix videos are very specific and, therefore, should probably be watched on an as-needed basis.   You can just follow the link to see the wide variety of topics.  Since it's at a conference, however, some of the information will be marketing-speaking, but there's a lot of good stuff in the videos as well.  The PDC however is much less marketing-ish and there were a few Silverlight 2 sessions.  Links: http://silverlight.net/learn/videocat.aspx?cat=8 and https://sessions.microsoftpdc.com/public/timeline.aspx.

Fourth, if you're the reading-type, then you may prefer the Silverlight 2 e-book at learn-silverlight-tutorial.com.  This e-book covers a ton of information.  Much like the 53-part series, I would mark this down as basic-level.  It covers a touches on a wide variety of topics.  However, much of the information is just that: "a touch".  It's not very deep, but it's rather wide.  Link: http://www.learn-silverlight-tutorial.com/

Fifth, Microsoft has always been good about providing QuickStarts.  These are kind of a cross between visual, text, and hands-on learning.  These are also the typical go to card for any one new to anything.  The ASP.NET quick starts are still incredibly popular these many years later.  The Silverlight ones are quite well done as well.  The topics are basic-intermediate and range from topics like general UI controls to cooler stuff like JavaScript/DOM interop.  However, you may feel completely free to absolutely ignore the completely worthless "web services" section.  Whoever wrote that thought he or she was writing about the hopelessly-flawed ASMX, not the image-of-beauty WCF and, therefore, didn't even remotely bother to obey the most fundamental of WCF purposes and practices (i.e. keep your address, binding, and contract away from your implementation!) Link: http://silverlight.net/quickstarts/

Speaking of WCF, the last resource I want to mention is my document entitled "Understanding WCF in Silverlight 2".  This one has received a lot of attention since I wrote it in November 2008.  In fact, it's now listed on the WCF MSDN home page.  It's there because I cover WCF from the ground up for both .NET and Silverlight in a very deep manner.  If you are new to WCF, SOA, or Silverlight, then this is a good place to start (of course, no bias here.)  I wrote this document to help both people new to WCF and Silverlight as well as those who have been working either either for a while.  Even if you're not too serious about Silverlight, you should still read this detailed document to understand WCF better.  I don't play around with introductory nonsense, I hit the ground running with best-practices and proper architectural principles.  Link: http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2

Though it's not a straight learning resource, I support I would also like to mention that you can always check out the Silverlight tag in my Delicous account: http://delicious.com/quantum00/silverlight.  However, keep in mind that just because I bookmark something, it doesn't mean I'm recommending the resource.  It just means it was interesting and/or provided some value to me.  You can expect this to be updated for the months to come.  I live off of my delicious account.

Another thing I would like to mention is that if you know WPF and web development, then you almost get Silverlight knowledge naturally.  Silverlight is essential a subset of WPF for the web.  You just take WPF, rip out a bunch of features, add just a handful of topics, move it to the web, and you have Silverlight.  Much of your skills are reusable if you already know WPF.  Actually, a lot of your skills are reusable if you're a .NET developer in general.  Just whip open Reflector and start looking through the framework, you'll see that there's a lot less than what's in the .NET framework, thus requiring much less learning time.

So, don't waste your money on books.  The blog is the new book.  Don't bother asking your employer for Silverlight training.  OK, well, if you just want some time off from work, sure, go ahead and ask.  Really, though, these resources will give you what you need for your Silverlight development.  In fact, if you were to compare the syllabus for an expensive course with the topics found in the first two sections of videos mentioned (97 of them!), you will see that the ROI for the course is virtually non-existent.

Links Summary

Understanding WCF Services in Silverlight 2

November 16, 2008

If you like this document, please consider writing a recommendation for me on my LinkedIn account.

Contents

Introduction

One of the most beautiful things about the Windows Communication Foundation (WCF) is that it's a completely streamlined technology.  When you can provide solutions to myriad of diverse problems using the same principles, you know you're dealing with a work of genius.  This is the case with WCF.  With a single service implementation, you can provide access to ASMX, PHP, Java, TCP, named pipe, and JSON-based services by add a single XML element for each type of connection you want to support.  On the flip side, with a single WCF client you can connect to each of these types of services, again, by adding a single like of XML for each.  It's that simple and streamlined.  Not only that, this client scenario works the same for both .NET and Silverlight.

In this document, I'm going to talk about how to access WCF services using Silverlight 2 without magic.  There will be no proxies, no generated code, no 3rd party utilities, and no disgusting "Add Service Reference" usage.  Just raw WCF.  This document will cover WCF connectivity in quite some depth.  We will talk about service setup, various WCF, SOA, and Silverlight paradigms, client setup,  some security issues, and a few supplemental features and techniques to help you aide and optimize service access.  You will learn about various WCF attributes, some interfaces, and a bunch of internals.  Though this document will be in depth, nothing will ever surpass the depth of MSDN.  So, for a more full discussion on any topic, see the WCF documentation on MSDN.

Even though we're focusing on Silverlight, most of what will be explained will be discussed in a .NET context and then applied to Silverlight 2.  That is, instead of learning .NET WCF and Silverlight WCF, you will .NET WCF and how to vary this for Silverlight.  This comparative learning method should help you both remember and understand the concepts better.  Before we begin, though, let's begin with a certain WCF service setup.  After all, we you don't have a service, we can't talk about accessing it.

Service Setup In Depth

When working with WCF, you are working with a completely streamlined system.  The most fundamental concept in this system is the ABC.  This concept scales from Hello World to the most complex sales processing system.  That is, for all WCF communication, you need an address, a binding, and a contract.  Actually, this is for any communication anywhere, even when talking to another person.  You have to know to whom, how, and what.  If you don't have these three, then there can't be any communication.

With these three pieces of information, you either create a service-side endpoint which a client will access or a client-side channel which the client will use to communicate with the service.

WCF services are setup using a 3 step method:

  • First, create a service contract with one or more operation contracts.
  • Second, create a service implementation for those contracts. 
  • Third, configure a service host to provide that implementation with an endpoint for that specific contract.

Let's begin by defining a service contract.  This is just a simple .NET interface with the System.ServiceModel.ServiceContractAttribute attribute applied to it.  This interface will contain various operation contracts, which are simply method signatures with the System.ServiceModel.OperationContractAttribute applied to each.  Both of these attributes are in the System.ServiceModel assembly.

Do not under any circumstances apply the ServiceContract attribute directly to the implementation (i.e. the class).  The ability to do this is probably the absolute worst feature in WCF.  It defeats the entire purpose of using WCF: your address, your binding, your contract and your implementation are complete separate.  Because this essentially makes your implementation your contract, all your configuration files will be incredibly confusing to those of us who know WCF well.  When I look for a contract, I look for something that starts with an "I".  Don't confuse me with "PersonService" as my contract.  Person service means person... service.  Not only that, but later on you will see how to use a contract to access a service.  It makes no sense to have my service access my service; thus with the implementation being the contract, your code will look painfully confusing to anyone who knows WCF.

Here's the sample contract that we will use for the duration of this document:

using System;
using System.ServiceModel;
//+
namespace Contact.Service
{
    [ServiceContract(Namespace = Information.Namespace.Contact)]
    public interface IPersonService
    {
        //- GetPersonData -//
        [OperationContract]
        Person GetPersonData(String personGuid);
    }
}

Keep in mind that when you design for WCF, you need to keep your interfaces as simple as possible.  The general rule of thumb is that you should have somewhere between 3 to 7 operations per service contract.  When you hit the 12-14 mark, it's seriously time to factor out your operations.  This is very important.  As I'll mention again later, in any one of my WCF projects I'll have upwards of dozens of service contracts per service.  You need to continuously keep in mind what your purpose is for creating this service, filtering those purposes through the SOA filter.  Don't design WCF services like you would a framework, which, even then shouldn't have many access points!

The Namespace property set on the attribute specified the namespace used to logically organize services.  Much like how .NET uses namespaces to separate various classes, structs, and interfaces, SOAP services use namespaces to separate various actions.  The name space may be arbitrarily chosen, but the client and service must just agree on this namespace. In this case, the namespace is the URI http://www.netfxharmonics.com/service/Contact/2008/11/.  This namespace will also be on the client.  This isn't a physical URL (universal resource locator), but a logical URI (universal resource identifier).  Despite what some may say, both terms are in active use in daily life.  Neither is more important than the other and neither is "deprecated".  All URLs are URIs, but not all URIs are URLs as you can see here.

Notice in this interface, there is a method interface that returns Person.  This is a data contract.  Data contracts are classes which have the System.Runtime.Serialization.DataContractAttribute attribute applied to them.  These have one or more data members, which are public or private properties or fields that have the System.Runtime.Serialization.DataMemberAttribute attribute applied to them.  Both of these attributes are in the System.Runtime.Serialization assembly.  This is important to remember; if you forget, you will probably assume them to be in the System.ServiceModel assembly and your contract will never compile.

Notice I said that data members are private or public properties or fields.  That was not a typo.  Unlike the serializer for the System.SerializableAttribute attribute, the serializer for DataContract attribute allows you to have private data members.  This allows you to hide information from developers, but allow services to see it.  Related to this is the how classes with the DataContract attribute differ from classes with the Serializable attribute.  When you use the Serializable attribute, you are using an opt-out model.  This means that when the attribute is applied to the class, each members is serializable.  You then opt-out particular fields (not properties; thus one major inflexibility) using the System.NonSerializedAttribute attribute.  On the other hand, when you apply the DataContract attribute, you are using an opt-in model.  Thus, when you apply this attribute, you must opt-in each field or property you wish to be serialized by applying the DataMember attribute.  Now to finally look at the Person data contract:

[DataContract(Namespace = Information.Namespace.Contact)]
public class Person
{
    //- @Guid -//
    [DataMember]
    public String Guid { get; set; }

    //- @FirstName -//
    [DataMember]
    public String FirstName { get; set; }

    //- @LastName -//
    [DataMember]
    public String LastName { get; set; }

    //- @City -//
    [DataMember]
    public String City { get; set; }

    //- @State -//
    [DataMember]
    public String State { get; set; }

    //- @PostalCode -//
    [DataMember]
    public String PostalCode { get; set; }
}

Note how simple this class is.  This is incredibly important.  You need to remember what this class represents: data moving over the wire.  Because of this, you need to make absolutely sure that you are sending only what you need.  Just because your internal "business object" has 10,000 properties doesn't mean that your service client will ever be able to handle it.  You can't get blood from a turnip.  Your business desires will never change the physics of the universe.  You need to design with this specific scenario of service-orientation in mind.  In the case of Silverlight, this is even more important since you are dealing with information that needs to get delegated through a web browser before the plug-in ever sees it.  Not only that, but every time you send an extra property over the wire, you are making your Silverlight application that less responsive.

When I coach architects on database design, I always remind them to design for the specific system which they'll be using (i.e. SQL Server) and always keep performance, space, and API usability in mind (this is why it's the job of the architect, not the DBA, to design databases!)  In the same way, if you are designing a system that you know will be used over the wire, account for that scenario ahead of time.  Much like security, performance and proper API design aren't "features", they're core parts of the system.  Do not design 10 different classes, each representing a property which will be used in another class which, in turn, will be serialized and sent over the wire.  This will be so absolutely massive that no one will ever be able to handle it.  If you have more than around 15 properties in your entire object graph, it's seriously time to rethink what you want to send.  And, never, ever, ever send an instance of System.Data.DataSet over the wire.  There has never been, is not now, and never will be any reason to ever send any instance of this type anywhere.  It's beyond massive and makes the 10,000 property data transfer object seem lightweight.  The fact that something is serializable doesn't mean that it should be.

This is main reason you should not apply the Serializable attribute to all classes.  Remember, this attribute follows an opt-out model (and a weak one at that).  If you want your "business objects" to work in your framework as well as over the wire, you need to remove this attribute and apply the DataContract attribute.  This will allow you to specify via the DataMember attribute which properties will be used over the wire, while leaving your existing framework completely untouched.  This is the reason the DataContract attribute exists!  Microsoft realized that the Serializable attribute is not fine grained enough for SOA purposes.  They also realized that there's no reason to force everyone in the world to write special data transfer objects for every operation.  Even then, use DataContract sparingly.  Just as you should keep as much private as possible and as much internal as possible, you want to keep as much un-serializable as possible.  Less is more.

In my Creating Streamlined, Simplified, yet Scalable WCF Connectivity document, I explain that these contracts are considered public.  That is, both the client and the service need the information.  It's the actual implementation that's private.  The client needs only the above information, where as the service needs the above information as well as the service implementation.  Therefore, as my document explains, everything mentioned above should be in a publicly accessible assembly separate from the service implementation to maximize flexibility.  This will also allow you to rely on the original contracts instead of relying on a situation where the contracts are converted to metadata over the wire and then converted to sloppily generated contracts.  That's slower, adds latency, adds another point of failure, and completely destroys your hand crafted, highly-optimized contracts.  Simply add a reference to the same assembly on both the client and server-side and you're done.  If multiple people are using the service, just hand out the public assembly.

At this point, many will try to do what I've just mentioned in a Silverlight environment to find that it doesn't seem to work.  That is, when you try to add a reference to a .NET assembly in a Silverlight project, you will get the following error message:

DotNetSilverlightReferenceMessageBox

Fortunately, this isn't the end of the world.  In my document entitled Reusing .NET Assemblies in Silverlight, I explain that this is only a Visual Studio 2008 constraint.  There's absolutely no technical reason why Silverlight can't use .NET assemblies.  Both the assembly and module formats are the same for Silverlight and .NET.  When you try to reference an assembly in a Silverlight project, Visual Studio 2008 does a check to see what version of mscorlib the assembly references.  If it's not 2.X.5.X, then it says it's not a Silverlight assembly.  So, all you need to do is modify your assembly to have it use the appropriate mscorlib file.  Of course, then it's still referencing the .NET System.ServiceModel and System.Runtime.Serialization assemblies.  Not a big deal, just copy/paste the Silverlight references in.  My aforementioned document explains everything you need to automate this procedure.

Therefore, there's no real problem here at all.  You can reuse all your contracts on both the service-side and on the client-side in both a .NET Silverlight environment.  As you will see a bit later, Silverlight follows an async communication model and, therefore, must use async-compatible service contracts.  At that time you may begin to think that you can't simply have a one-stop shop for all your contract needs.  However, this isn't the case.  As it turns out .NET can do asynchronous communication too, so when you create that new contract, you can keep it right next to your original service contract.  Thus, once again, you have a single point where you keep all your contracts.

Moving on to step 2, we need to use these contracts to create an implementation.  The service implementation is just a class which implements a service contract.  The service implementation for our document here is actually incredibly simple:

using System;
//+
namespace Contact.Service
{
    public class PersonService : Contact.Service.IPersonService
    {
        //- @GetPersonData -//
        public Person GetPersonData(String personGuid)
        {
            return new Person
            {
                FirstName = "John",
                LastName = "Doe",
                City = "Unknown",
                Guid = personGuid,
                PostalCode = "66062",
                State = "KS"
            };
        }
    }
}

That's it.  So, if you already have some logic you know is architecturally sound and you would like to turn it into a service.  Create an interface for your class and add some attributes to the interface.  That's your entire service implementation.

Step 3 is to configure a service host with the appropriate endpoints.  In our document, we are going to be using an HTTP based service.  Thus after we setup a new web site, we create a Person.svc file in the root and add to it a service directive specifying our service implementation.  Here's the entire Person.svc file:

<%@ ServiceHost Service="Contact.Service.PersonService" %>

No, I'm not joking.  If you keep your implementation in this class as well, then you are not using WCF properly.  In WCF, you keep your address, your binding, your contract, and your implementation completely separate.  By putting your implementation in this file, you are essentially tying the address to the implementation.  This defeats the entire purpose of WCF.  So, again, the above code is all that should ever be in any svc file anywhere.  Sometimes you may have another attribute set on your service directive, but this is basically it.

This is an unconfigured service host.  Thus, we must configure it.  We will do this in the service web site's web.config file.  There's really only one step to this, but that one step has a prerequisite.  The step is this: setup a service endpoint, but this requires a declared service.  Thus, we will declare a service and add it to an endpoint.  An endpoint specifies the WCF ABC: an address (where), a binding (how), and a contract (what).  Below is the entire web.config file up to this point:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Contact.Service.PersonService">
        <endpoint address="" binding="basicHttpBinding" contract="Contact.Service.IPersonService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

This states that there can be "basicHttpBinding" communication through Contact.Service.IPersonService at address Person.svc to Contact.Service.PersonService.  Let's quickly cover each concept here.

The specified address is a relative address.  This means that the value of this attribute is appended onto the base address.  In this case the base address is the address specified by our web server.  In the case of a service outside of a web server, then you can specify an absolute address here.  But, remember, when using a web server, the web server is going to control the IP address and port bindings.  Our service is at Person.svc, thus we have already provided for us the base URL.  In this case the address is blank, but you will use this address attribute if you add more endpoints as you will see later.

The binding specifies how the information is to be format for transfer.  There's actually nothing too magical about a binding, though.  It's really just a collection of binding elements and pre-configured parameter defaults, which are easily changed in configuration.  Each binding element will have at a minimum two binding elements.  One of these is a message encoding binding element, which will specify how the message is formatted.  For example, the message could be text (via the TextMessageEncodingBindingElement class; note: binding elements are in the System.ServiceModel.Channels namespace), binary (via the BinaryMessageEncodingBindingElement class), or some other encoding.  The other required binding element is the transport binding element, which specified how the message is to go over the wire.  For example, the message could go over HTTP (via the HttpTransportBindingElement), HTTPS (via the HttpsTransportBindingElement), TCP (via the TcpTransportBindingElement), or even a bunch of others.  A binding may also have other binding elements to add more features.  I'll mention this again later, when we actually use a binding.

The last part of an endpoint, the contract, has already been discussed earlier.  One thing that you really need to remember about this though is that you are communication through a contract to the hosted service.  If you are familiar with interface based development in .NET or COM, then you already have a strong understanding of what this means.  However, let's review.

If a class implements an interface, you can access the instantiated object through the interface.  For example, in the following code, you are able to access the Dude object through the ISpeak interface:

interface ISpeak
{
    void Speak(String text);
}

class Dude : ISpeak
{
    public void Speak(String text)
    {
        //+ speak text
    }
}

public class Program
{
    public void Run()
    {
        ISpeak dude = new Dude();
        dude.Speak("Hello");
    }
}

You can think of accessing a WCF service as being exactly like that.  You can even push the comparison even further.  Say the Dude class implemented IEat as well.  Then we can access the instantiated Dude object through the IEat interface.  Here's what I mean:

interface ISpeak
{
    void Speak(String text);
}

interface IEat
{
    void Eat(String nameOfFood);
}

class Dude : ISpeak, IEat
{
    public void Speak(String text)
    {
        //+ speak text
    }
}

public class Program
{
    public void Run()
    {
        IEat dude = new Dude();
        dude.Eat("Pizza");
    }
}

In the same way, when configuring a WCF service, you will add an endpoint for contract through which you would like your service to be accessed.

Though it's beyond the scope of this document, WCF also allows you to version contracts.  Perhaps you added or removed a parameter from your contract.  Unless you want to break all the clients accessing the service, you must keep the old contract applied to your service (read: keep the old interface on the service class) and keep the old endpoint running by setting up a parallel endpoint.

You will add a new service endpoint every time you change your version, change your contract, or change your binding.  On a given service, you have have dozens of endpoints.  This is good thing.  Perhaps you provide for four different bindings with two of them having two separate configurations each, three different contracts, and 2 different versions of one of the contracts.  In this document, we are going to start out with one endpoint and add more later.

Now we have setup a complete service.  However, it's an incredibly simple service setup, thus not requiring too much architectural attention.  When you work with WCF in a real project, you will want to organize your WCF infrastructure to be a bit more architecturally friendly.  In my document entitled Creating Streamlined, Simplified, yet Scalable WCF Connectivity, I explain streamlining and simplifying WCF connectivity and how you can use a private/public project model to simplify your WCF connectivity.  See that document for more information on streamlining WCF services.

Service Access Without Magic

Now we may turn our attention to the client application.  To begin, let me start off by reminding everyone that you shouldn't ever use "Add Service Reference" in Visual Studio for magical service client creation.  The code is incredibly verbose, hard to manageable, edits are prone to being overwritten, and it's almost always used as an excuse to not actually learn WCF.  There are few things worse than having to deal with people who thing they know a product simply because they know how to use a mouse.  There are reasons why Juval Lowy, in all his books and talks, repeatedly tells people to avoid using this flawed feature.  Fortunately, as professionals, we have the ability to understand how to do things without magic.

As I've mentioned many times already, WCF relies on the concept of the ABC.  We've seen how we configure a WCF host by creating an endpoint specifying an address, binding and contract.  As it turns out, this is all that's required on the client side as well.  For both .NET and Silverlight, you merge an address and a binding with a contract in a channel factory to create a channel.  This isn't just fancy conceptual architect speak, this is exactly what your code would look like (the sign of really good architecture!)  Below is the .NET version of what I mean:

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:1003/Person.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
//+
Person person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");

In this you have an address (the EndpointAddress object), a binding (BasicHttpBinding), and a contract (IPersonService) meeting in System.ServiceModel.ChannelFactory<TServiceContract> to create a channel which implements the IPersonService interface (and others).  We can then call through our local interface to the channel, which then calls the remote service through the service interface.  No magic is required.  You don't need any "proxy" or anything.  WCF is literally all about the ABC on the service and on the client.

A few moments ago I mentioned that a binding is nothing more than a series of binding elements.  At this time I would like to prove this to you.  In the above sample, we are using a BasicHttpBinding on the client to communicate to a BasicHttpBinding on the service.  This is slightly "magical".  Let's peel back the covers to see what's really going on.  The BasicHttpBinding is the WCF implementation of the WS-I Basic Profile standard used by ASMX services and most PHP clients.  In other words, it's the basic SOAP binding.  Internally though, it's really nothing more than a combination of the TextMessageEncodingBindingElement and, depending on your settings, either HttpTransportBindingElement or HttpsTransportBindingElement with the message version set to SOAP 1.1.

To prove this, let's completely remove the BasicHttpBinding from our client.  Then let's create an instance of the System.ServiceModel.Channels.CustomBinding class.  This class allows us to make our own bindings from our own or preexisting binding elements.  In this case, all we want to do is add the TextMessageEncodingBindingElement, setting the message version to SOAP 1.1 and add the HttpTransportBindingElement.  With this, we have creating a binding that fits exactly what our service expects.  Here's what we're talking about:

CustomBinding customBinding = new CustomBinding();
customBinding.Elements.Add(new TextMessageEncodingBindingElement
{
    MessageVersion = MessageVersion.Soap11
});
customBinding.Elements.Add(new HttpTransportBindingElement());
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:1003/Person.svc");
//+
IPersonService personService = new ChannelFactory<IPersonService>(customBinding, endpointAddress).CreateChannel();

If you think that's wild, you will be in shock when you realize that you don't even need to use code to create a custom binding.  Let's completely remove the CustomBinding and address from our code and just do the exact same thing in web.config.  Here is our new code:

IPersonService personService = new ChannelFactory<IPersonService>("PersonServiceCustomHttpBinding").CreateChannel();

Doesn't get much simpler than that.  Now take a look at our web.config:

<system.serviceModel>
  <bindings>
    <customBinding>
      <binding name="HttpTextCustomBinding">
        <textMessageEncoding messageVersion="Soap11" />
        <httpTransport/>
      </binding>
    </customBinding>
  </bindings>
  <client>
    <endpoint name="PersonServiceCustomHttpBinding" 
              bindingConfiguration="HttpTextCustomBinding" 
              address="http://localhost:1003/Person.svc" 
              binding="customBinding" 
              contract="Contact.Service.IPersonService" />
  </client>
</system.serviceModel>

Believe it or not, our service still works perfectly.

Up to this point we have been discussing WCF in general, it's now time to move towards Silverlight.  The ABC and channel concepts still apply, but, since we are in the world of the web, there's one difference in how we access the services from our clients: we are dealing with asynchronous calls.

The Async Pattern

If you are familiar with the concepts of AJAX calls, then you should already be familiar with what I'm talking about.  To put it simply, instead of calling a "do" method, you basically set a callback and call "beginDo".  Then, instead of obtaining a response from "beginDo", we wait for a callback from the service.  Think of it like phone tag between two people who never answer their phone.  Person A calls person B and says "call me back at X".  Then Person B calls Person A back at X; you don't sit there on someone's voicemail waiting for them to pick up (...like we did in the days of answering machines.)

When this idea is brought to the .NET/Silverlight world, we have something called the Async Pattern, which states that asynchronous methods are to follow the following pattern:

public IAsyncResult BeginOperation(/* <parameters> */, AsyncCallback callback, Object state)
public /* <return> */ EndOperation(IAsyncResult result)

If you're never seen this before, then, it's high time you become deeply familiar with it.  This pattern is used all over the place in myriad of different contexts.  You can use MSDN to find various examples involving this pattern, or just keep reading to see how it's used to get the general idea.  If you are going to take Silverlight seriously, then you absolutely must master this pattern.

Not only that, but you must also be very proficient with asynchronous call chains.  This is when you call one async operation, wait for the callback, then that callback begins another async operation, whose callback may call another async operation.  You just chain the async calls down the line to have a steady, deterministic program flow.  This, of course, requires knowledge of the Async Pattern to which we now return our focus.

When working with in Silverlight, this Async Pattern is the type of call pattern that you will be using for just about all service access with or without WCF.  For example, there will be no GetPersonData method which returns a Person object.  Instead, there will be a BeginGetPersonData method which returns an IAsyncResult object (which you may or may not use).  Then, you wait for a callback, which has an IAsyncResult again which you use to obtain a result from EndGetPersonData.  This actually means that our service contract in Silverlight will look slightly different than our service contract for .NET.  Here's our Silverlight version:

using System;
using System.ServiceModel;
//+
namespace Contact.Service
{
    [ServiceContract(Namespace = Information.Namespace.Contact)]
    public interface IPersonService
    {
        //- BeginGetPersonData -//
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginGetPersonData(String personGuid, AsyncCallback callback, Object state);

        //- LoadPerson -//
        Person EndGetPersonData(IAsyncResult result);
    }
}

Notice that we are now following the Async Pattern and that the OperationContract attribute has declaratively stated that we are following the pattern via the AsyncPattern property.  We may now rewrite our original .NET service-call code to follow the new paradigms and service contract to allow Silverlight interaction.  Here's our new code:

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:1003/Person.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
//+
AsyncCallback asyncCallBack = delegate(IAsyncResult result)
{
    Person person = ((IPersonService)result.AsyncState).EndGetPersonData(result);
    this.Dispatcher.BeginInvoke(delegate
    {
        spMain.Children.Add(new TextBlock
        {
            Text = person.FirstName
        });
    });
};
personService.BeginGetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6", asyncCallBack, personService);

Notice the first three lines are identical.  After this, not much remains the same.  Instead of doing a simple service-call with a synchronous response, we must set a callback and begin a request.  In this particular example, the asyncCallBack object is being given an anonymous method to the BeginGetPersonData method.  This anonymous method block will be called when the service calls returns a response back.

Take note of the third parameter in the BeginGetPersonData.  Per the Async Pattern, this is "state".  This is similar to the Tag object found in VB and in WPF.  You can use this to place just about anything you want to send back to the callback.  In this case, since we're it's an anonymous method, it's optional, but if the callback were a named method, then the callback may obtain that state by pulling the AsyncState property from the IAsyncResult object passed to the callback.  In this example, I'm sending the channel itself as the state so that I can access the channel from the callback.  This is important because this is how I'm able to call the EndGetPersonData method and retrieve the service operation response data, a Person object in this case.

Notice also also that the callback has a call to Dispatcher.BeginInvoke.  You must do this if you are on a visual element and want to access visual elements in your callback.  This will grant you access to the UI thread.  Without this, an exception will be thrown.  In this case we are adding a TextBlock to a StackPanel.  For the duration of this document, the following method will be used to write our output to the StackPanel:

//- $Write -//
private void Write(String text)
{
    this.Dispatcher.BeginInvoke(delegate
    {
        spMain.Children.Add(new TextBlock
        {
            Text = text
        });
    });
}

External Web Site Access

Having said all that, if you were to try and run the code I sent to you based on our current service configuration, nothing would actually work.  Why's that?  Because in our original service-setup the service is hosted in a different web site than the web site itself.  The service web site does nothing but WCF hosting, while our application web site hosts our Silverlight application.  This basically allows you to keep all your entities highly cohesive and reusable.  However, in this case, we are running up against a security wall.  By default, you cannot use Silverlight to access a web site which differs by domain, IP address, or port number. 

Fortunately, there's an easy way around this: you just need to add a ClientAccessPolicy.xml file in the service root.  Here's a sample ClientAccessPolicy.xml file:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

This particular example basically allows everyone everywhere to access the service, granting access to everything.  This may be what you want or, perhaps, you want to lock it down a bit by placing a URI of the format http://www.tempuri.org/ in place of the *.  Perhaps you even want to add multiple domain elements or, on the other end of the spectrum, restrict access to only a particular service path.

Now while this file looks all well and good, our Silverlight service call still won't work. Why in the world not?  Because for WCF in Silverlight to call a service outside of the local web site, you must also specify what headers to allow.  In our case, we want to allow the SOAPAction header.  The SOAPAction header is what a SOAP service uses to specify what action to run on the service.

Here's our new policy:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Now our WCF Silverlight service will work flawlessly.

For all the information you would ever need on this file, see Network Security Access Restrictions in Silverlight 2 on MSDN.

Configuration Based Access

Our service client call at this point is fully programmatic.  This is nice, but perhaps you would like to utilize WCF configuration instead of creating Binding and Endpoint elements manually.  This is a great idea, but how in the world do we access configuration in Silverlight when Silverlight is on the client-side, running in a web browser?  As it turns out, Silverlight actually does include a configuration file, which gets embedded in to the final XAP file, the ServiceReferences.ClientConfig file.

To utilize this configuration feature, we first need to create the file and add it to our Silverlight project.  Then, we must set its build action to Content.  In Visual Studio 2008, you do this in the properties window for that file.  This will force the file to be zipped in with the rest of the contents of the XAP file, which, if you didn't know, is really nothing more than a ZIP file readable by any ZIP client, much like Word 2007's DOCX format.

At this point, you may just copy/paste the configuration from a .NET WCF client to this Silverlight configuration file.  Here's basically what it will look like at this point:

<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="http://localhost:1003/Person.svc" binding="basicHttpBinding" contract="Contact.Service.IPersonService" name="BasicHttpBinding_IPersonService" />
    </client>
  </system.serviceModel>
</configuration>

At this point can change our code to use the configuration instead of the created binding and endpoint address objects:

IPersonService personService = new ChannelFactory<IPersonService>("BasicHttpBinding_IPersonService").CreateChannel();
//+
AsyncCallback asyncCallBack = delegate(IAsyncResult result)
{
    Person person = ((IPersonService)result.AsyncState).EndGetPersonData(result);
    Write(person.FirstName);
};
personService.BeginGetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6", asyncCallBack, personService);

Now, once again, while this looks nice, when you compile and run the Silverlight application you will notice that it doesn't even pretend to work.  Why? For some reason, you actually need to declare a basicHttpBinding element in the configuration file.  Here's the new configuration file:

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding />
    </bindings>
    <client>
      <endpoint address="http://localhost:1003/Person.svc" binding="basicHttpBinding" contract="Contact.Service.IPersonService" name="BasicHttpBinding_IPersonService" />
    </client>
  </system.serviceModel>
</configuration>

At this point, the Silverlight client will have full connectivity with the service.

Strongly Typed Client

At this point we could stop.  The thing works.  Mission Accomplished.  However, when designing software, you want to make sure people call fall into success.  In this case, a developer might forget how to create a WCF channel.  Even then, system internals have nothing to do with the core competency of what's going on.  Business developers need to be working on providing a business solution, not writing WCF interaction code.  Thus, it's often a good idea to hide the internals of something before anyone else uses it.  Even I, as a non-business developer, who love internals and gets great benefits from their understanding, prefer not to see internals in my every day development.  Therefore, I normally hide the internal mechanics of the WCF channel by creating a client abstraction.

As with WCF in .NET, you may use the System.ServiceModel.ClientBase<T> class to create an abstraction of the internal WCF channel mechanics.  However, due to the Async Pattern, using ClientBase in Silverlight is drastically different how I described it's usage for .NET in "Creating Streamlined, Simplified, yet Scalable WCF Connectivity".  Creating a concrete ClientBase class is still fairly straightforward though.

The first thing we need to do is create a class that inherits from ClientBase<IYourServiceContract> where IYourServiceContract is, well, your service contract.  However, unless you want a very complicated class, do not implement the IYourServiceContract on this ClientBase like you would normally do in .NET.  Instead, for each operation in your service contract, create a method in this class.  Don't worry about following the Async Pattern.  Our point in creating this abstraction is to hide the internals mechanics, not to simply rearrange them.  Having said that, you still need to have a callback parameter if your method returns a response.

In addition to this, make sure your method names make sense.  By convention, you should suffix each operation method in your ClientBase with "Async".  Then, inside the method, call your method prefixed with "Begin" on the channel created by the ClientBase class.  Totally confused?  Here's what I mean:

//- @GetPersonDataAsync -//
public void GetPersonDataAsync(String personGuid, EventHandler<ClientEventArgs> callback)
{
    Channel.BeginGetPersonData(personGuid, GetPersonDataCallback, callback);
}

In reality, all you're doing is taking a call and passing it to the Channel with different parameters.  Essentially you are hiding the Async Pattern used by this channel method with something that's more natural to developers.  In this channel call, the second parameter, GetPersonDataCallback, is the WCF callback which is called when the actual service call is complete and the third parameter is the state for the Async Pattern.  Here's the GetPersonDataCallback method:

//- $GetPersonDataCallback -//
private void GetPersonDataCallback(IAsyncResult result)
{
    EventHandler<ClientEventArgs> callBack = result.AsyncState as EventHandler<ClientEventArgs>;
    if (callBack != null)
    {
        callBack(this, new ClientEventArgs
        {
            Object = EndGetPersonData(result)
        });
    }
}

Since we set the callback as the state in the service call, it follows that we can pull that out and use it to send the response data back to the calling method using the standard .NET event pattern.  In this case, the ClientEventArgs class is a simple EventArgs class which holds the response object:

public class ClientEventArgs : EventArgs
{
    //- @Object -//
    public Object Object { get; set; }
}

Now notice that when we are populating this newly created ClientEventArgs, we are setting it's Object property to the result of the EndGetPersonData, which is the second of the two Async Pattern components.  It's implementation is extremely simple:

//- $EndGetPersonData -//
private Person EndGetPersonData(IAsyncResult result)
{
    return Channel.EndGetPersonData(result);
}

Notice also that our ClientBase callback and End methods are private, thus completely concealing the internal WCF mechanics from developers.

There's at least one more method we need to add to our class for it to be complete: the constructors.  Personally, I like to add a constructor which accepts a System.ServiceModel.Channels.Binding object and a System.ServiceModel.EndpointAddress object as well as an overload which accepts a string representing the endpoint configuration name.  These constructors basically do nothing but bridge to the base class:

//- @Ctor -//
public PersonClient(String endpointConfigurationName)
    : base(endpointConfigurationName) { }
public PersonClient(System.ServiceModel.Channels.Binding binding, EndpointAddress address)
    : base(binding, address) { }

Thus, we have successfully created a ClientBase class to abstract the internal mechanics for developers.  To sum up, here's the complete class:

using System;
using System.ServiceModel;
//+
namespace SilverlightClient
{
    public class PersonClient : ClientBase<Contact.Service.IPersonService>
    {
        //- @Ctor -//
        public PersonClient(String endpointConfigurationName)
            : base(endpointConfigurationName) { }
        public PersonClient(System.ServiceModel.Channels.Binding binding, EndpointAddress address)
            : base(binding, address) { }

        //+
        //- @GetPersonDataAsync -//
        public void GetPersonDataAsync(String personGuid, EventHandler<ClientEventArgs> callback)
        {
            Channel.BeginGetPersonData(personGuid, GetPersonDataCallback, callback);
        }

        //- $GetPersonDataCallback -//
        private void GetPersonDataCallback(IAsyncResult result)
        {
            EventHandler<ClientEventArgs> callBack = result.AsyncState as EventHandler<ClientEventArgs>;
            if (callBack != null)
            {
                callBack(this, new ClientEventArgs
                {
                    Object = EndGetPersonData(result)
                });
            }
        }

        //- $EndGetPersonData -//
        private Contact.Service.Person EndGetPersonData(IAsyncResult result)
        {
            return Channel.EndGetPersonData(result);
        }
    }
}

If you need to add more operations, and you most definitely will, all you need to do is copy/paste this pattern and do a which rename of a new things here and there.  You could create a Visual Studio code snippet to setup this pattern as well.  Using this class is now as simple as the following:

PersonClient personClient = new PersonClient("BasicHttpBinding_IPersonService");
personClient.GetPersonDataAsync("F488D20B-FC27-4631-9FB9-83AF616AB5A6", OnServiceCallback);

Then, of course, there's the callback method:

//- $OnServiceCallback -//
private void OnServiceCallback(Object sender, ClientEventArgs ea)
{
    Person person = ea.Object as Person;
    if (person == null)
    {
        return;
    }
    //+
    Write(person.FirstName);
}

As simple as this is, though, you could actually keep the simplicity of this usage and still upgrade the class to be a bit more general.  For this reason, I created my ObjectClient<TServiceContract> class.  Here's an example of using it:

ObjectClient<IPersonService> objectClient = new ObjectClient<IPersonService>("BasicHttpBinding_IPersonService");
objectClient.Begin("GetPersonData", OnObjectServiceCallback, null, "F488D20B-FC27-4631-9FB9-83AF616AB5A6");

Then, here's the service callback:

//- $OnObjectServiceCallback -//
private void OnObjectServiceCallback(Object sender, ObjectClient<IPersonService>.ClientEventArgs ea)
{
    Person person = ea.LoadResult<Person>();
    Write(person.LastName);
}

The mechanics of this class follow the same idea as the previous ClientBase, but this one does not use ClientBase, but, rather, creates the channel itself.  Then, when the "Begin" method is called, the class internally passes the parameters to the proper "BeginMethodName" method property via dynamic invocation.  Internally, the service callback also uses dynamic invocation to call "EndMethodName" to obtain the result.  The result is then passed to the original callback using the same ClientEventArgs as seen in the PersonClient example.

Below is the ObjectClient code in its entirety:

#region Copyright
//+ Copyright © Jampad Technology, Inc. 2008
//++ Lead Architect: David Betz [MVP] <dfb/davidbetz/net>
#endregion
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
//+
namespace Nalarium.ServiceModel
{
    public class ObjectClient<TServiceContract> where TServiceContract : class
    {
        //- @ClientEventArgs -//
        public class ClientEventArgs : EventArgs
        {
            //- @Object -//
            public Object Object { get; set; }

            //- @UserState -//
            public Object UserState { get; set; }

            //+
            //- @LoadResult -//
            public TResult LoadResult<TResult>()
            {
                if (this.Object is TResult)
                {
                    return (TResult)this.Object;
                }
                //+
                return default(TResult);
            }
        }

        //- $ObjectClientState -//
        private class ObjectClientState
        {
            //- @Callback -//
            public EventHandler<ClientEventArgs> Callback { get; set; }

            //- @MethodName -//
            public String MethodName { get; set; }

            //- @UserState -//
            public Object UserState { get; set; }
        }

        //+
        //- $Channel -//
        private TServiceContract Channel { get; set; }

        //- $ContractType -//
        private Type ContractType { get; set; }

        //+
        //- @Ctor
        private ObjectClient()
        {
            ContractType = typeof(TServiceContract);
        }
        public ObjectClient(Binding binding, EndpointAddress address)
            : this()
        {
            Channel = new ChannelFactory<TServiceContract>(binding, address).CreateChannel();
        }
        public ObjectClient(String endpointConfigurationName)
            : this()
        {
            Channel = new ChannelFactory<TServiceContract>(endpointConfigurationName).CreateChannel();
        }

        //+
        //- @Begin -//
        public void Begin(String methodName, Object state, params Object[] parameterArray)
        {
            Begin(methodName, null, state, parameterArray);
        }
        public void Begin(String methodName, EventHandler<ClientEventArgs> callback, Object state, params Object[] parameterArray)
        {
            if (parameterArray != null)
            {
                Array.Resize<Object>(ref parameterArray, parameterArray.Length + 2);
            }
            else
            {
                parameterArray = new Object[2];
            }
            parameterArray[parameterArray.Length - 1] = new ObjectClientState
            {
                Callback = callback,
                MethodName = methodName,
                UserState = state
            };
            parameterArray[parameterArray.Length - 2] = new AsyncCallback(OnCallback);
            ContractType.InvokeMember("Begin" + methodName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, Channel, parameterArray);
        }

        //- $OnCallback -//
        private void OnCallback(IAsyncResult result)
        {
            ObjectClientState state = result.AsyncState as ObjectClientState;
            if (state == null)
            {
                return;
            }
            Object obj = ContractType.InvokeMember("End" + state.MethodName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, Channel, new Object[] { result });
            if (state.Callback != null)
            {
                state.Callback(this, new ClientEventArgs
                {
                    Object = obj,
                    UserState = state.UserState
                });
            }
        }
    }
}

Feel free to upgrade it, modify it, or use it however you would like.

Security - Communication over SSL

At this point I would like to turn out attention to a critical part of WCF development: security. Many times, if not most of the time, you will be dealing with some sort of sensitive information in your application. This goes for Silverlight as much as it does for .NET. Fortunately, secure WCF interaction is essentially the same for both.  Before we begin though, we need to update our service in order for it to handle secure connectivity.  To do this, we are going to create a separate service from our Person service, called SecurePersonService.  In most situations, you would just have a single service to handle both, but for the sake of this document we're going to keep them separate.

Before we add security to our service though, we need to have an SSL certificate installed on the server.  This is the same type of certificate you would have if you wanted to provide a checkout experience on an e-commerce web site.  If you already have an SSL certificate, great, if not, then you will need to go through the motions to install one.  To install one for IIS6 or IIS7, just follow the instructions at http://blog.functionalfun.net/2008/05/how-to-create-server-certificate-for.html.  This post explains how you can easily get a free 90-day signed SSL certificate from a certificate provider.

Once you have the certificate installed, you need to then configure the service for SSL.  We haven't yet created the service, but that's OK.  We know what it's going to be called.  To configure our BasicHttpBinding service for SSL you essentially need to set the security mode to Transport in a binding configuration and specify the certificate in a service behavior.  Here's the new configuration:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="SecureBasicHttpBinding">
          <security mode="Transport" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SecurePersonServiceBehavior">
          <serviceCredentials>
            <serviceCertificate 
              findValue="localhost" 
              storeLocation="LocalMachine" 
              storeName="My" 
              x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="Contact.Service.PersonService">
        <endpoint address="" binding="basicHttpBinding" contract="Contact.Service.IPersonService" />
      </service>
      <service name="Contact.Service.SecurePersonService" behaviorConfiguration="SecurePersonServiceBehavior">
        <endpoint bindingConfiguration="SecureBasicHttpBinding" 
                  address="" binding="basicHttpBinding" contract="Contact.Service.IPersonService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

There are two conceptual notes that should probably be mentioned at this point:

First, a binding configuration changes the defaults of a particular binding.  As I mentioned earlier, a binding is really just a collection of binding elements with some pre-set parameters.  In this case, we are applying a particular binding configuration to an endpoint to change the security from "None" to "Transport" (which is SSL in this case).

Second, behaviors essentially allow you to declaratively, either via configuration or programmatically via attributes, modify how a particular part of your service operates.  You can have all kinds of different behaviors at different levels.  For example, you can use an operation behavior to modify something about an operation.  We will see this later when we use an operation behavior to apply operation-level security.  In our configuration here, we are applying a service behavior to modify the service to use a particular certificate.

Next, for the time being, let's copy/paste our PersonService implementation as a new class called SecurePersonService.  Again, this is only for the sake of this demo.  In reality, there's no reason to use the word "Secure" for this service.  Then, let's create a SecurePerson.svc file in our service web site root and insert the following service declaration:

<%@ ServiceHost Service="Contact.Service.SecurePersonService" %>

At this point we have an SSL BasicHttpBinding service setup.  We can now alter alter our Silverlight client to use SSL.  This is really just a matter of setting the BasicHttpBinding security more to Transport and changing the URL from the HTTP based URL to the HTTPS one.  Here's how we have modified our previous Silverlight WCF client to allow SSL access:

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
//+ step 1 of 2: set security mode
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
//+ step 2 of 2: set to https _and_ set proper relative endpoint
EndpointAddress endpointAddress = new EndpointAddress("https://localhost/SecurePerson.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();

Those two steps are the only steps involved.  Silverlight is not set to use the new SSL service.

Having said that, if you try to run the Silverlight client, it won't work.  Why?  Well, as Tim Heuer, Senior Program Manager for Silverlight points out, you can't rely on the existing ClientAccessPolicy.xml configuration we used previously.  Previously we allowed the "*" domain, which allows all non-secure clients in.  This does not include HTTPS clients.  Thus, we need to specify them explicitly.  Here is our new ClientAccessPolicy.xml file:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers= "SOAPAction">
        <domain uri="http://*"/>
        <domain uri="https://*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Now our Silverlight client will communicate successfully with the service over SSL.  But, SSL only secures the data going over the wire, it doesn't say anything about who can access the data.  For this we need to add some form of authentication.

Security - UserName Authentication

If we were working in .NET, we could just use the WsHttpBinding to use the WS-Security standard to send our username and password to our service.  Silverlight 2.0, however, doesn't include this binding.  This doesn't mean we can't make username/password authentication happen.  We could actually use a WebRequest technique that we will cover later to communicate with a WsHttpBinding service, but let's keep with BasicHttpBinding for the time being.  In this case, all we need to do is add the username and password to the message to be sent over our secure SSL connection and have it checked at the other end.  This is really as easy as it sounds.

Regardless of whether you are on the service-side or the client-side, you will have something called an operation context.  This houses the information for the current operation.  You can think of it as a the WCF operation version of HttpContext in ASP.NET.  In fact, much like HttpContext, the OperationContext object is a single.  You access it via System.ServiceModel.OperationContext.Current. As you progress in your WCF projects, you will find yourself going to the operation context time and time again for various reason.  It's an incredibly important feature of WCF that provides much value to service development on both the service and client side.

Of the many properties in this context, there is one called OutgoingMessageHeaders of type System.ServiceModel.Channels.MessageHeaders.  As the name suggestions this houses the message headers that are being sent out.  Likewise there's also an IncomingMessageHeaders object of the same type, which contains the header information that has been received.  These are just opposite sides of the coin.  Both outgoing and incoming headers are like request headers in the web world.  Outgoing headers are the "request headers" being sent and incoming headers are the "request headers" received on the other end.  This works the same for both the service-side and client-side.

To enable authorization, we just need to add both the username and password to the OutgoingMessageHeader object on the client and read them from the IncomingMessageHeader object on the service.  In Silverlight, this looks like this:

MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;
messageHeadersElement.Add(MessageHeader.CreateHeader("UserName", "", "JohnDoe"));
messageHeadersElement.Add(MessageHeader.CreateHeader("Password", "", "MyPassword"));

Notice there is no mention of the service we are going to access.  When the service-call happens, the information will automatically be applied in the background and sent over the wire.

Now while this sounds great, we see a reoccurring theme: it doesn't work.  Why?  If you try to do this, you will find that OperationContext.Current is null.  The singleton has not yet been created.  Well, that kind of throws a wrench in things.  Fortunately, though, this is easily remedied.  All we need to do is declare an operation context scope.  This basically means instantiating a System.ServiceModel.OperationContextScope object, passing it an existing operation context or something which implements the System.ServiceModel.IContextChannel interface.  We obviously don't have the former, but what about the latter?

As it turns out, the channel created by our channel factory doesn't only implement our service contract (IPersonService), but it also implements IContextChannel.  Thus, we are able to pass this to the operation context scope, which will then create the operation context, allowing us to add the headers and make our call.  Here's our new service call:

using (OperationContextScope scope = new OperationContextScope((IContextChannel)personService))
{
    MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;
    messageHeadersElement.Add(MessageHeader.CreateHeader("UserName", "", "JohnDoe"));
    messageHeadersElement.Add(MessageHeader.CreateHeader("Password", "", "MyPassword"));
    //+
    Person person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
}

Note that the operation context scope implements the System.IDisposable interface, thus allowing you to wrap it in a using block in C#.

At this point we can turn our attention to the service.  This is actually about as simple as what we did on the client-side, if not simpler.  All we need to do is see if the IncomingMessageHeaders object on our operation context contains our UserName and Password headers.  If they do, then extract them and validate them.  If all if well, then run the service logic.

To check to see if a particular message header is in the IncomingMessageHeaders object, use the FindHeader method.  This will return the index of the header or -1 if the header was not found.  Since both of our headers must exist, the sum of the indexes must be at least 0.  -1 would mean that one of the two headers is missing whereas -2 would mean that both are missing.  Therefore, if the sum is at least 0, we can grab the header information, which we do using the GetHeader<T> method.  This is a generic method, so specify the type that you would like your header value to be as T.  In our case they will both be System.String.  Once we have pulled the username and password, we can validate them and run our service logic.  Here's our entire service up to this point:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
//+
namespace Contact.Service
{
    public class SecurePersonService : Contact.Service.IPersonService
    {
        //- @GetPersonData -//
        public Person GetPersonData(String personGuid)
        {
            MessageHeaders messageHeadersElement = OperationContext.Current.IncomingMessageHeaders;
            Int32 id = messageHeadersElement.FindHeader("UserName", "") + messageHeadersElement.FindHeader("Password", "");
            if (id > -1)
            {
                String username = messageHeadersElement.GetHeader<String>("UserName", "");
                String password = messageHeadersElement.GetHeader<String>("Password", "");
                if (username == "JohnDoe" && password == "MyPassword")
                {
                    return new PersonService().GetPersonData(personGuid);
                }
            }
            //+
            return null;
        }
    }
}

Now at this point we could reuse this same technique to secure each operation in our service.  However, the technical term for doing this is insanity.  This is absolutely crazy.  There absolutely has to be a better way of doing this than dealing with the internal mechanics of message headers for each and every single operation in your service.  We need something that will validate the username and password information before our logic ever runs so that we never, ever have to see it.  Fortunately, there is.  This is exactly the value an operation behavior provides.  They are also incredibly straightforward to implement.

Before we do that though, we need to create operation invoker.  We do this by creating a class which implements the System.ServiceModel.Dispatcher.IOperationInvoker interface.  There are many member signatures in this interface, but we only care about the Invoke method.  Every time you call an operation, you "invoke" the operation much like how you "invoke" a method via reflection.  Earlier we saw how we passed an anonymous method to an Invoke method in WPF so we could access the UI thread.  This is the same idea.  When you run something, you "invoke" it.  For an operation invoker, when an operation is called, the Invoke method is called to run the actual operation logic.  Our mission is to house validation logic in our invoker and, if validation succeeds, have the invoker call the original service operation invoker.

We install an operation invoker using an operation behavior.  An operation behavior is a class which implements the System.ServiceModel.Description.IOperationBehavior interface.  This interface has four method signatures, but we really only care about one of them.  Not only that, but the only thing this method will do is set our Invoker.  Before this can matter though, we have to have a way to apply our bit to our operation.  The operation behavior may set the operation invoker, but who sets the operation behavior?  As it turns out, operation behaviors may be applied declaratively through attributes.  This is rather interesting as it allows us to have our operation behavior class inherit from System.Attribute, thus making our operation behavior completely self-sufficient.

It's that time again to move from the lecture hall to the lab.  We will first turn our attention to the operation behavior.  Below is the entire operation behavior:

using System;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
//+
namespace Contact.Service.Behavior
{
    [AttributeUsage(AttributeTargets.Method)]
    public class SecurityOperationBehavior : Attribute, IOperationBehavior
    {
        //- @AddBindingParameters -//
        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            //+ blank
        }

        //- @ApplyClientBehavior -//
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
            //+ blank
        }

        //- @ApplyDispatchBehavior -//
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.Invoker = new SecurityOperationInvoker(dispatchOperation.Invoker);
        }

        //- @Validate -//
        public void Validate(OperationDescription operationDescription)
        {
            //+ blank
        }
    }
}

As you can see, it's just a simple attribute whose attribute usage states that it may only be applied to methods.  Notice also that the only method we care is the ApplyDispatchBehavior method and, as mentioned before, the only thing were doing is setting the new invoker, passing the original invoker to its constructor.  Let's now turn to our operation invoker:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
//+
namespace Contact.Service.Behavior
{
    public class SecurityOperationInvoker : IOperationInvoker
    {
        //- $InnerOperationInvoker -//
        private IOperationInvoker InnerOperationInvoker { get; set; }

        //+
        //- @Ctor -//
        public SecurityOperationInvoker(IOperationInvoker operationInvoker)
        {
            this.InnerOperationInvoker = operationInvoker;
        }

        //+
        //- @AllocateInputs -//
        public Object[] AllocateInputs()
        {
            return InnerOperationInvoker.AllocateInputs();
        }

        //- @Invoke -//
        public Object Invoke(Object instance, Object[] inputs, out Object[] outputs)
        {
            //+ authorization
            MessageHeaders messageHeadersElement = OperationContext.Current.IncomingMessageHeaders;
            Int32 id = messageHeadersElement.FindHeader("UserName", "") + messageHeadersElement.FindHeader("Password", "");
            if (id > -1)
            {
                String username = messageHeadersElement.GetHeader<String>("UserName", "");
                String password = messageHeadersElement.GetHeader<String>("Password", "");
                SecurityValidator.Authenticate(username, password);
                //+
                return InnerOperationInvoker.Invoke(instance, inputs, out outputs);
            }
            //+
            throw new FaultException<InvalidOperationException>(new InvalidOperationException(SecurityValidator.Message.InvalidCredentials), SecurityValidator.Message.InvalidCredentials);
        }

        //- @InvokeBegin -//
        public IAsyncResult InvokeBegin(Object instance, Object[] inputs, AsyncCallback callback, Object state)
        {
            return InnerOperationInvoker.InvokeBegin(instance, inputs, callback, state);
        }

        //- @InvokeEnd -//
        public Object InvokeEnd(Object instance, out Object[] outputs, IAsyncResult result)
        {
            return InnerOperationInvoker.InvokeEnd(instance, out outputs, result);
        }

        //- @IsSynchronous -//
        public Boolean IsSynchronous
        {
            get { return InnerOperationInvoker.IsSynchronous; }
        }
    }
}

At first glance it may seem like there's a lot going on here, but if you look closely you will see that there are only three things of note here.  First, there is the InternalOperationInvoker property.  This just hold the original operation invoker so we can call it later.  Second, every other member except Invoke does nothing but call the invoker in InternalOperationInvoker.  Third, the Invoke method is not really doing anything but what we've already seen in the service operation.  The only difference is that upon validation, instead of doing the actual logic, the Invoke method just calls the Invoke method of our InternalOperationInvoker property.  So, it's not really all that busy after all.

With our operation behavior created, we can now return to modify our service operation.  All we need to do is remove all the validation logic and apply our new SecurityOperationBehavior attribute.  Our service operation now looks like this:

//- @GetPersonData -//
[SecurityOperationBehavior]
public Person GetPersonData(String personGuid)
{
    return new PersonService().GetPersonData(personGuid);
}

That's a lot better than before, isn't it?  With this new toy at your disposal, whenever you want to secure a new operation in your service, just apply the attribute and move on. 

Before moving on, note that if you would like to see another example of using operation behaviors, see my Minima Blog Engine 3.1 source code.  Minima is my training software to demonstrate many areas of .NET and it relies heavily on WCF.

Handling Exceptions

We now have an authentication model for our WCF connectivity in our Silverlight application.  There is one more thing we could do to improve this.  Returning null from a service when validation failed is a good way to cause no end to confusion.  The worst error is seeing no error.  Therefore, we need to throw an exception if validation fails.  Continuing in how we have been discussing things, let's move our attention back to the .NET world to discuss some concepts and theory.  Then let's angle our knowledge a bit to make way for the Silverlight world.

To begin, you need to understand that the concept of an exception is a .NET concept.  The messages over the wire have absolutely nothing to do with .NET and, therefore, have no idea what an exception is.  Instead, messages over the wire and service-oriented architecture in general have a concept called a fault, which essentially serves the same purpose as an exception.  Therefore, if you were to throw an exception in a service, the SOA world won't have the first clue what you're talking about.  Not only that, but when your client hears about the exception, it won't see an exception, but, rather a signal that there was some sort of a catastrophic error, thus closing your client channel (our IPersonService instance).  In other words, the following in the service will break your client:

String message = "Invalid credentials";
throw new System.InvalidOperationException(message);

You can, however, get around this by telling your WCF service to include exception information in fault.  You can set this in configuration or in your service host factory.  I'm not going to demonstrate this because I don't want to encourage this cop-out technique.  This is only to be used for debugging.  Do you really want the fully-detailed exception message and stack trace to go out into all the world to see?  This would be even worst than turning ASP.NET custom errors off.  This is the image of a security flaw.

WCF provides the proper mechanism for dealing with exceptions with the System.ServiceModel.FaultException<T> class.  This allows us to to throw exceptions as fault.  There's also a System.ServiceModel.FaultException, from which FaultException<T> inherits.  You can either throw the non-generic one to send a simple message or you can use the generic one to send a message and the exception type.  The generic one will probably be the one you use most often.

To use FaultException<T>, first instantiate the exception you would like to throw then pass that object as well as the exception message to the FaultException<T> instance.  Then you may throw the FaultException<T> instance.  That is, instead of throwing the InvalidOperationException as seen in the last example, do the following:

String message = "Invalid credentials";
throw new FaultException<System.InvalidOperationException>(new System.InvalidOperationException(message), message);

This will allow your client code to catch the exception gracefully and won't send your private stack trace for the world to see.  Here's the code to handle this:

try
{
    person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
}
catch (FaultException ex)
{
    Response.Write(ex.Message);
}

At this point our service-side fault exception code is the same as the following:

throw new FaultException("Invalid credentials");

As I've already mentioned, using the FaultException class will send back a message.  This is exactly what FaultException<T> at this point too.  To make FaultException<T> work the way it was designed, you need to declare a fault contract on your service-side service contract.  You do this by applying the System.ServiceModel.FaultContract attribute to your operation contract.  Here's our new service contract:

using System;
using System.ServiceModel;
//+
namespace Contact.Service
{
    [ServiceContract(Namespace = Information.Namespace.Contact)]
    public interface IPersonService
    {
        //- GetPersonData -//
        [OperationContract]
        [FaultContract(typeof(InvalidOperationException))]
        Person GetPersonData(String personGuid);
    }
}

Now we are able to catch the various different fault exceptions a service may return:

try
{
    person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
}
catch (FaultException<InvalidOperationException> ex)
{
    Response.Write(ex.Message);
}

At this point some may suggest that, since we are only interested in security validation, we should turn our attention toSystem.Security.SecurityException as follows:

throw new System.Security.SecurityException("Invalid credentials");

This special exception will actually be a fault over the wire, give you graceful error handling, and it also doesn't publish your stack trace.  One thing you need to remember about this exception, though, is that you don't catch the same exception that has been thrown.  You actually catch System.ServiceModel.Security.SecurityAccessDeniedException.  Not only that but the message that was sent from the service, isn't the message that will show in your client.  The client side exception will always say "Access is denied.".  Here's an example:

try
{
    person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
}
catch (System.ServiceModel.Security.SecurityAccessDeniedException ex)
{
    Response.Write(ex.Message);
}

You probably shouldn't rely on this mechanism though.  WCF will replace the SecurityException with a Fault over the wire, but not in all places.  For example, the above code will work beautifully if you are throw the exception from an operation, but if you throw it in an operation behavior, your client will see, not SecurityAccessDeniedException, but rather a FaultException (not the generic one either).  You should use FaultException<SecurityException> either as this can cause the real exception to be System.Net.Sockets.SocketException, which is absolutely catastrophic.  For a security validation error, I use FaultException<InvalidOperationException> as we've already seen.

Now, I must apologize at this point for getting you excited about all the awesomeness of faults handling in WCF, because... none of that works in Silverlight.  Yeah.  I know.  It's like "why didn't you say that earlier!!??"  Well, it's important to understand the underlying mechanics of the ideal, before you can work around them into the real-- otherwise, you're just making stuff up as you go.  Not only that, you need to make sure you understand WCF in general before you understand WCF in Silverlight.  Chances are that your WCF services will do more than simply serve Silverlight.

The reason none of this works in the Silverlight world is because has absolutely no concept of a fault.  It actually can't.  With this specific service, when your service call fails validation, your Silverlight application will only see a 404 error with the text "The remote server returned an error: NotFound".  When a fault is thrown, regardless of how pretty you make it, the HTTP status code is not 200, where 200 means that everything went OK.  This is a problem for Silverlight.

Silverlight, as we know, runs in the context of a web browser.  Because of this, Silverlight is only provided the information that a web browser allows it.  When a response is returned to Silverlight with a status code other than 200, the web browser intercepts it and never tells Silverlight about it.  It's kind of like when you're at the office and you go to search for a critical piece of information only to find that your company's content filter blocks that particular technology web site thinking it was inappropriate.

There are various ways around this and every single technique that I know of requires you to modify your service.  The method we are going to use modifies the service a tiny bit, but it does so in a reusable way.  We are essentially going to create a custom FaultDetail class which we will implement in our Person data contract.  If an exception is thrown on the service, a fault detail will be created and added to our Person object.  Then, when we receive a response on the client side, we can check to see if FaultDetail is null.  If not, then there was a fault. 

However, I don't want to do this for all my service-clients.  Service clients that can handle service faults are going to see the real fault.  There's no reason to confuse whoever is accessing our service by having a separate FaultDetail.  Having an error in two places can lead to disasters and mass confusion.  Mindless consistency is often the fastest way to catastrophic disaster.  You can't say you drive 40 miles per hour at all times because you strive for consistency.  This can kill pedestrians in school zones and kill you on the interstate.  We must be flexible to the context of each situation.  We must seek congruency, not consistency.  Therefore, we will only set the FaultDetail object when a specific message header is present.  For our service, we will call this message header "DoesNotHandleFault".  Note this isn't "IsSilverlight".  This makes our FaultDetail technique reusable for other technologies that do not handle faults.

Enough lecture, back to the lab.  First, let's create our FaultDetail object.  This can simply be a class with some properties.  In this example, I have a Message property as well two constructors, one to accept a message and open to accept an exception:

using System;
using System.ServiceModel;
//+
namespace General.Service
{
    public class FaultDetail
    {
        //- @Message -//
        public String Message { get; set; }

        //+
        //- @CreateFaultDetail -//
        public static FaultDetail CreateFaultDetail(Exception exception)
        {
            return CreateFaultDetail(exception.Message);
        }
        public static FaultDetail CreateFaultDetail(String message)
        {
            return new FaultDetail
            {
                 Message = message
            };
        }
    }
}

At this point, you could take this idea further and iterate through the InnerExceptions of the exception and add nested FaultDetail messages.  That's a mission for you, if you choose you accept it.

Next, let's create an interface that will signal to us that a particular service-side data contract can handle a FaultDetail:

namespace General.Service
{
    public interface IContainsFaultDetail
    {
        FaultDetail FaultDetail { get; set; }
    }
}

Let's now implement the interface:

using System;
using System.Runtime.Serialization;
//+
using General.Service;
//+
namespace Contact.Service
{
    [DataContract(Namespace = Information.Namespace.Contact)]
    public class Person : IContainsFaultDetail
    {
        //++
        //+ more properties here
        //++
        //- @FaultDetail -//
        [DataMember]
        public FaultDetail FaultDetail { get; set; }
    }
}

You may be curious to know how this service-side data contract change will affect the rest of the clients which consume this service.  It's actually really simple: it doesn't.  The client will not break simply because it doesn't know how to deserialize something.  Actually, in .NET, if the client-side data contract didn't have data members the service was sending back to it, but implemented System.Runtime.Serialization.IExtensibleDataObject, the data would go into the data contract's ExtensionData property, or as I like to call it "the data member bucket". So, you aren't breaking anything by adding data members to your service-side data contracts.  As a side note, this works the other way too.  If your client sends more information than the service knows about, the service won't break either and, if its data contract implemented IExtensibleDataObject on a service-side data contract, the data will likewise go into the ExtensionData property.  Like I said though, this is in .NET.  Silverlight does not support this interface.  Of course, Silverlight can still send extra stuff to the service, which will be in .NET.

The last task on the service-side is to add the FaultDetail functionality to our service.  We could either add the functional to each and every single operation or we could simply extend the operation behavior that we had already created.  I'm voting for the later.  Essentially what we are going to do is wrap all the logic in our operation invoker Invoke logic in a try-catch block.  Then, if an exception is thrown, we can check to see if the "DoesNotHandleFault" message header is set.  If it is, set the FaultDetail on the return object.  If it isn't, then simply rethrow the exception.

This all seems pretty simple, right?  Well, there are some problems with this.  First, you want to make this reusable.  Therefore, you cannot assume anything about the operation return type other than the fact that everything inherits from System.Object.  You could easily get around this by checking to see if our IContainsFaultDetail interface is on the object.  If it is, then you can set the FaultDetail through this interface.  You don't even need to know the actual type.  However, what if the object is null?  Just instantiate it first, right?  Again, you don't know the type.  Fortunately, however, the wonderful world of reflection is at our disposal.

To get around this problem, we need to first see if there is even a problem at all.  This means checking to see if our return object is null.  If not, then you're all set to check for the interface and set the FaultDetail through that interface.  If it is null, then we need to use reflection to obtain the type of the return object.  This is actually hidden in our InnerOperationInvoker which we saved when we instantiated our operation invoker.  To be more specific, inside our InnerOperationInvoker is a property named Method.  This method is of type System.Reflection.MethodInfo, which, in turn, has a property named ReturnType of type System.Type which is exactly what we need.  Then, we use the System.Activator::CreateInstance method to create an instantiated object using the value of ReturnType.  At this point we are able to check for our IContainsFaultDetail interface and setting the FaultDetail.

Once more, let's switch from lecture to lab.  Below is our new Invoke method for our operation invoker based on the concepts I've just explained:

//- @Invoke -//
public Object Invoke(Object instance, Object[] inputs, out Object[] outputs)
{
    outputs = new Object[] { };
    MessageHeaders messageHeadersElement = OperationContext.Current.IncomingMessageHeaders;
    Object returnObject = null;
    try
    {
        //+ authorization
        Int32 id = messageHeadersElement.FindHeader("UserName", "") + messageHeadersElement.FindHeader("Password", "");
        if (id > -1)
        {
            String username = messageHeadersElement.GetHeader<String>("UserName", "");
            String password = messageHeadersElement.GetHeader<String>("Password", "");
            SecurityValidator.Authenticate(username, password);
            //+
            return InnerOperationInvoker.Invoke(instance, inputs, out outputs);
        }
        //+
        throw new FaultException<InvalidOperationException>(new InvalidOperationException(SecurityValidator.Message.InvalidCredentials), SecurityValidator.Message.InvalidCredentials);
    }
    catch (Exception ex)
    {
        if (messageHeadersElement.FindHeader("DoesNotHandleFault", "") > -1)
        {
            if (returnObject == null)
            {
                Type invokerType = InnerOperationInvoker.GetType();
                PropertyInfo pi = invokerType.GetProperty("Method");
                MethodInfo mi = (MethodInfo)pi.GetValue(InnerOperationInvoker, null);
                Type returnType = mi.ReturnType;
                Type interfaceType = returnType.GetInterface("General.Service.IContainsFaultDetail");
                if (interfaceType != null)
                {
                    returnObject = Activator.CreateInstance(returnType);
                }
            }
            if (returnObject != null && returnObject is IContainsFaultDetail)
            {
                ((IContainsFaultDetail)returnObject).FaultDetail = FaultDetail.CreateFaultDetail(ex.Message);
            }
        }
        else
        {
            throw;
        }
    }
    //+
    return returnObject;
}

The explanation that I have already provided should help you understand each part of what's going on here.  There is, however, one part of this that may cause you problems if you don't implement this technique correctly.  Notice the Invoke method accepts an out parameter named outputs.  And out parameter is an incredibly powerful C# feature that requires the method on which it is placed to give the parameter a value, which the method caller may then.  If your method does not give the parameter a value, your code will not compile.  In many cases, setting an out parameter to null will be sufficient.  In this case, this will cause a serialization error when the service reply is created.  Therefore, in this example, I'm setting the outputs parameter to an empty object array.  This will satisfy both the compiler as well as WCF.

At this point, we can move to the client-side.  The first thing we need to do is copy our FaultDetail, IContainsFaultDetail, and new Person data contract to our Silverlight project.  Note that you do NOT need to do this for any other clients for the reasons I've already already mentioned.  The only clients that need these changes are the clients which are going to use the FaultDetail directly.

Next, let's add our "DoesNotHandleFault" message header in our Silverlight client.  You can do this in the same place you set your other message headers:

using (OperationContextScope scope = new OperationContextScope((IContextChannel)personService))
{
    MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;
    messageHeadersElement.Add(MessageHeader.CreateHeader("UserName", "", "JohnDoe"));
    messageHeadersElement.Add(MessageHeader.CreateHeader("Password", "", "MyPassword12341234"));
    //+ allows returning of a FaultDetail object
    messageHeadersElement.Add(MessageHeader.CreateHeader("DoesNotHandleFault", "", true));
    //+
    personService.BeginGetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6", asyncCallBack, personService);
}

Then, in our callback, check for the FaultDetail object:

AsyncCallback asyncCallBack = delegate(IAsyncResult result)
{
    Person person = ((IPersonService)result.AsyncState).EndGetPersonData(result);
    String text = String.Empty;
    if (person.FaultDetail != null)
    {
        text = person.FaultDetail.Message;
    }
    else
    {
        text = person.FirstName;
    }
    //+ the rest of your callback here
};

Now you have the ability to catch faults in Silverlight 2.  There's, however, one quite serious problem with this method though.  What happens when your operation doesn't return a data transfer object (DTO) like our Person class?  There's no setting a FaultDetail on an array, a list, an Int32, or a string.

Though it's generally a redundant and architecturally questionable idea, in these cases you really need to create a wrapper response class.  As a service-oriented architect, I only care about the service contracts.  If the service contracts have nothing more than a bunch of request response messages, then I'm seriously slowed down.  They tell me absolutely nothing.  How can I know anything about an operation's response by looking at GetPersonDataResponse?  In these situations, it takes me much longer to get at the heart of what's going on because I need to understand with X number of methods and (2 * X) number of custom objects (and look them up on a chart every time I forget what's what!)

Thus, though services are to accept a very specific set of parameters and return a very specific element.  For our scenario, however, you need to do this.  To create a DTO, just create a class which contains a property for your operation return object and as well as a FaultDetail property.  As I've mentioned, this is incredibly redundant as what I've just described is exactly what SOAP envelope does with a fault.  But, since Silverlight will never see those messages, we are rather forced to emulate them.

JSON Service Connectivity

If you've been paying attention to the examples thus far, we have only been using the BasicHttpBinding binding.  This is because Silverlight doesn't handle bindings like WsHttpBinding, NetTcpBinding, or NetNamedPipeBinding.  However, since we're on the web, we might create a Silverlight application to replace an AJAX component which used JSON to communicate to a WebHttpBinding WCF service endpoint.  Or, perhaps, you just prefer to use a WebHttpBinding on your WCF service.  Therefore, we need the ability to access JSON services efficiently.  To do this, we turn to the System.Net namespace, namely the WebRequest class.

Essentially what we want to do is create an instance of the System.Net.WebRequest class and setup an async call chain.  If you recall, an async chain is when the callback of one call makes another call and its callback may potentially make another call.  Before you can do any of this, though, you need to know the full URI you are going to access.  This URI is the base endpoint address of the service combined with the relative endpoint address combined with the name of the service operation you are going to access.

We know from our service setup that the base address of our service is http://localhost:1003/Person.svc.  The relative address is configured on the service side.  Here's a configuration snippet from the service:

<service name="Contact.Service.PersonService">
  <endpoint address="json" binding="webHttpBinding" contract="Contact.Service.IPersonService" behaviorConfiguration="JsonEndpointBehavior" />
</service>

The endpoint address, "json", is the second piece of information required, the relative endpoint address.  The third piece of information in our case is "GetPersonData".  Thus the full URI we need to pass to our WebRequest object is http://localhost:1003/Person.svc/json/GetPersonData.

Once we create a WebRequest object, we need to make sure the content type is set to "application/json" and make sure the HTTP method is set to POST.  Without both of these set, we will get nothing but errors all over the place.  With these set, we are then able to enter into an async chain of the steps that occur in a WebRequest.

The process begins by calling the BeginGetRequestStream method on our WebRequest object, passing it a callback.  When that callback is called, we are then, per the Async Pattern, we able to call the EndGetRequestStream, which, if you recall, requires the IAsyncResult which was passed to our callback.  At this point we are able to write information to the service and call BeginGetResponse, passing it another callback.  Then, when that callback is called, we can call the EndGetResponse, passing it the new IAsyncResult object to obtain a System.Net.WebResponse object.  Finally, we call GetResponseStream on this WebResponse object, which gives us the response data sent back to us from the service.  Here is a complete example of using the WebRequest object in this way:

using System;
using System.Collections.Generic;
using System.Json;
using System.Net;
//+
namespace SilverlightClient
{
    public class WcfJsonClient
    {
        //- @JsonValueEventArgs -//
        public class JsonValueEventArgs : EventArgs
        {
            //- @JsonValue -//
            public JsonValue JsonValue { get; set; }

            //- @JsonType -//
            public JsonType JsonType { get; set; }

            //- @ValueAsText -//
            public String ValueAsText
            {
                get
                {
                    System.Text.StringBuilder builder = new System.Text.StringBuilder();
                    System.IO.StringWriter writer = new System.IO.StringWriter(builder, System.Globalization.CultureInfo.CurrentCulture);
                    JsonValue.Save(writer);
                    //+
                    return builder.ToString();
                }
            }
        }

        //- @Complete -//
        public event EventHandler<JsonValueEventArgs> Callback;

        //+
        //- $PostJsonData -//
        private String PostJsonData { get; set; }

        //+
        //- @PostHttpRequest -//
        public void PostHttpRequest(String endpoint, String methodName)
        {
            PostHttpRequest(endpoint, methodName, String.Empty, null);
        }
        public void PostHttpRequest(String endpoint, String methodName, String jsonData)
        {
            PostHttpRequest(endpoint, methodName, jsonData, null);
        }
        public void PostHttpRequest(String endpoint, String methodName, String jsonData, Dictionary<String, String> headerDictionary)
        {
            WebRequest request = WebRequest.Create(new Uri(endpoint + "/" + methodName));
            this.PostJsonData = jsonData;
            request.Method = "POST";
            request.ContentType = "application/json";
            if (headerDictionary != null)
            {
                foreach (String key in headerDictionary.Keys)
                {
                    request.Headers[key] = headerDictionary[key];
                }
            }
            request.BeginGetRequestStream(new AsyncCallback(OnPostBegin), request);
        }

        //- $OnPostBegin -//
        private void OnPostBegin(IAsyncResult result)
        {
            WebRequest request = result.AsyncState as WebRequest;
            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(request.EndGetRequestStream(result)))
            {
                if (!String.IsNullOrEmpty(this.PostJsonData))
                {
                    writer.Write(this.PostJsonData);
                }
                writer.Close();
                //+ response
                request.BeginGetResponse(new AsyncCallback(OnPostComplete), request);
            }
        }

        //- $OnPostComplete -//
        private void OnPostComplete(IAsyncResult result)
        {
            WebRequest request = result.AsyncState as WebRequest;
            using (WebResponse response = request.EndGetResponse(result))
            {
                OnComplete(new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd());
            }
        }

        //- #OnComplete -//
        protected void OnComplete(String data)
        {
            if (Callback != null)
            {
                JsonValue jsonValue = (JsonValue)JsonObject.Load(new System.IO.StringReader(data))["d"];
                Callback(this, new JsonValueEventArgs
                {
                    JsonValue = jsonValue,
                    JsonType = jsonValue is JsonArray ? JsonType.Array : JsonType.Object
                });
            }
        }
    }
}

Here you can see the WebRequest setup as well as the async chain.  Notice also how this example accepts a System.Collections.Generic.Dictionary<T1, T2> object.  Using this we are able to set custom HTTP headers on to our client.  Using HTTP headers is an awesome way of communicating with a service.  We have already seen that SOAP services use the SOAPAction header to specify what operation to run at the other end.  You could do something similar in your JSON services as well.

Normally at this point I would like show you an example of using this client, but we aren't done explaining it.  One part of this client example that we haven't discussed is how to deal with the response JSON data.  At this point our JSON data is just raw text.  Ideally, we would take this raw text, run it through deserialization and be done with things.  However, one hitch here is that an unmodified WCF JSON service likes to send back JSON with full namespaces for each member.  Here's an example of what I mean:

{
    "d": {
        "__type": "Person:http:\/\/www.netfxharmonics.com\/service\/Contact\/2008\/11\/",
        "City": "Unknown",
        "FirstName": "John",
        "Guid": "F488D20B-FC27-4631-9FB9-83AF616AB5A6",
        "LastName": "Doe",
        "PostalCode": "66062",
        "State": "KS"
    }
}

This kind of gets in the way of simple deserialization.  Fortunately, that's not a problem as Silverlight 2 provides a different way to access JSON data through it's System.Json.JsonObject housed in the System.Json assembly.  Be careful, though, every time you add an assembly to your Silverlight application, you increase the size of the Silverlight XAP file.  When you add the 52k System.JSON assembly, you add 21k to the size of the XAP file.  In this case, this takes the size of the XAP file from 12k to 33k.  That's a huge increase.  So, think ahead on how and if you really want to access JSON WCF services using this technique.

If you notice from the client, when we the last client callback is called, the static System.Json.JsonObject.Load method is called to load a stream or TextReader into a System.Web.JsonValue object.  This gives us a representation we can use to access any information we want by accessing the indexer of the object.  Before we can access our data, though, we need to open the data envelope.  This is that "d" section in the WCF JSON response message.  This is as simple as accessing the "d" indexer on the JsonValue object as this example shows:

JsonValue jsonValue = (JsonValue)JsonObject.Load(new StringReader(data))["d"];

This JsonValue object created here contains the WCF response information.  The JsonValue class itself is the base class for System.Json.JsonArray and System.Json.JsonObject. Unless you know what your service is returning, you need to test which type the JsonObject.Load class created.  This is as simple as the following:

JsonType jsonType = value is JsonArray ? JsonType.Array : JsonType.Object;

If you're working with a JsonObject, you may then access any member of the JSON data you want.  You do this by reading values from a JsonValue into a stream or text writer.  For example, here's the code to access the FirstName value:

StringBuilder builder = new StringBuilder();
StringWriter writer = new StringWriter(builder);
jsonValue["FirstName"].Save(writer);
//+
String firstName = builder.ToString().Replace("\"", "");

Since you would be using this regularly, it's a good idea for us to place this in a method (or even in a "Reader" class):

//- $ReadJsonValue -//
private string ReadJsonValue(JsonValue jsonValue, String field)
{
    StringBuilder builder = new StringBuilder();
    jsonValue[field].Save(new StringWriter(builder));
    //+
    return builder.ToString().Replace("\"", "");
}

At this point, you have enough information to see how this WcfJsonClient class can be used.  Here's how we can use it:

WcfJsonClient client = new WcfJsonClient();
client.Complete += OnJsonServiceCallback;
client.PostHttpRequest("http://localhost:1003/Person.svc/json", "GetPersonData", @"{ ""personGuid"": ""F488D20B-FC27-4631-9FB9-83AF616AB5A6"" }");

This is, of course, not complete without the callback method:

//- $OnJsonServiceCallback -//
private void OnJsonServiceCallback(Object sender, WcfJsonClient.JsonValueEventArgs ea)
{
    Write(ReadJsonValue(ea.JsonValue, "State"));
}

As I've mentioned, we can work with arrays as well.  In .NET though, we really only talk about arrays for value types.  If we have a series of reference types, a collection feels much better.  Therefore, let's assume that we the following operation to our service:

//- GetPersonList -//
[OperationContract]
List<Person> GetPersonList( );

What's interesting about this is that System.Collections.Generic.List<T> likes to become an array when going over the wire.  When dealing with SOAP services, a List is an array over the wire.  The same goes for JSON as well.  This is where that JsonArray type comes in to play.  This object is incredibly easy to work with.  Essentially it's a series of JsonValue objects.  Not only that, but JsonArray has an indexer and it implements the IEnumerable<JsonValue> interface, thus allowing us to access it's elements via a foreach loop.  In our case, each of these elements will be of the type JsonObject, which we already know how to deal with.  Here's a complete example of interacting with the above service operation:

WcfJsonClient wcfJsonClient = new WcfJsonClient();
wcfJsonClient.Callback += delegate(Object sender, WcfJsonClient.JsonValueEventArgs ea)
{
    List<Person> personList = new List<Person>();
    JsonArray array = (JsonArray)ea.JsonValue;
    foreach (JsonValue jsonValue in array)
    {
        Person person = new Person
        {
            City = ReadJsonValue(jsonValue, "City"),
            FirstName = ReadJsonValue(jsonValue, "FirstName"),
            LastName = ReadJsonValue(jsonValue, "LastName"),
            PostalCode = ReadJsonValue(jsonValue, "PostalCode"),
            State = ReadJsonValue(jsonValue, "State"),
            Guid = ReadJsonValue(jsonValue, "Guid"),
        };
        personList.Add(person);
        //+
        Write(person.FirstName);
    }
    //+
    Write("Person count: " + personList.Count.ToString());
};
wcfJsonClient.PostHttpRequest("http://localhost:1003/Person.svc/json", "GetPersonList");

One aspect of this WcfJsonClient class that you may not have realized is that you could easily make it dual purpose with very few changes.  If you added a second callback for XML parsing and change the content type, your "WcfJsonClient" becomes "WcfXmlJsonClient".  This WebRequest technique itself can be used for just about anything.  You could load CVS data or even access SOAP services manually if you wanted, giving you the ability to interact with WsHttpBinding services.  If you know how to communicate with an HTTP service at the wire-level, then the WebRequest can probably make the connection happen.

The only other type of response you would ever really need to parse is a primitive, which is represented by the System.Json.JsonPrimitive, which also inherits from JsonValue.  You don't need to do anything special with these at all.  Just pull the value from them just as you would a value from JsonObject.  In our case, this means running it through the ReadJsonValue method.

Thread Waiting

As we have just seen with our JSON client, many times when working in the Async Pattern, you will have an async chain.  This is an effective way to manage the order or events in an application.  However, depending on what you're doing, this model may not be the entirely optimal.  Fortunately, we have another option: a thread wait.

Thread waiting has been in .NET since the beginning and is very effective in Silverlight to help us control the workflow of our applications.  To use a thread wait, you create an System.Threading.AutoResetEvent object and call it's WaitOne method.  This causes execution in the current thread to pause.  Execution will resume when the object's Set method is called.

So, you can call WaitOne immediately after a service call and have the service call's callback call Set to continue execution.  This allows you to keep a linear flow of your application instead of doing async chaining.  An important note about this, though, is that you don't want to call WaitOne on the UI thread.  This will basically lock up your web browser.  Instead, wrap your service calls and WaitOne call in a new thread.  This will cause that thread to pause, not the UI thread.  Here's the basic usage:

private AutoResetEvent wait = new AutoResetEvent(false);

//+
//- @OnButtonClick -//
public void OnButtonClick(Object sender, System.Windows.RoutedEventArgs ea)
{
    new Thread(new ThreadStart(delegate
    {
        //+ basicHttpBinding call
        ObjectClient<IPersonService> objectClient = new ObjectClient<IPersonService>("BasicHttpBinding_IPersonService");
        objectClient.Callback += OnServiceCallback;
        objectClient.Begin("GetPersonData", "F488D20B-FC27-4631-9FB9-83AF616AB5A6");
        wait.WaitOne();
        //+ webHttpBinding call
        WcfJsonClient wcfJsonClient = new WcfJsonClient();
        wcfJsonClient.Complete += OnJsonServiceCallback;
        wcfJsonClient.PostHttpRequest("http://localhost:1003/Person.svc/json", "GetPersonData", @"{ ""personGuid"": ""F488D20B-FC27-4631-9FB9-83AF616AB5A6"" }");
    })).Start();
}

In this example, a new thread will start and make an ObjectClient service call.  The thread will then be immediately pause.  It will remain paused until the following callback runs the wait.Set method, which will resume execution allowing the WcfJsonClient to then run.

//- $OnServiceCallback -//
private void OnServiceCallback(Object sender, ObjectClient<IPersonService>.ClientEventArgs ea)
{
    this.Dispatcher.BeginInvoke(delegate
    {
        //+ do stuff here
        wait.Set();
    });
}

Using DevServer

If you get seriously deep into HTTP-based service-development in either a Silverlight, AJAX, or general .NET context, there will definitely come a time your work when you need to know what messages are going over the wire, or if messages are going over the wire.  In a strictly Silverlight context, you might even want to make sure your Silverlight client is even looking for a ClientAccessPolicy.xml file.  Fortunately, there is a way to view all this information in a streamlined manner.

My NetFXHarmonics DevServer is a development web server which provides multi-instance web server hosting and the ability to look at the traffic in and out of each web server.  In addition, using DevServer profiles, you can load up entire sets of web servers to quickly setup and teardown different development environments.

To use it, just register your servers in the DevServer configuration file, setup a profile, and either set the startup profile or use a command line argument to specify what profile to load.  This will load up all your development web servers at once.  Here's a sample configuration:

<jampad.devServer>
  <startupProfiles activeProfile="Client">
    <profile name="Client">
      <server key="ClientWS" />
      <server key="ClientSVC" />
    </profile>
  </startupProfiles>
  <servers>
    <server key="ClientWS" name="ClientWS" port="1001"
                virtualPath="/" physicalPath="C:\Project\WCFService\WebSite">
    </server>
    <server key="ClientSVC" name="ClientSVC" port="1003"
                virtualPath="/" physicalPath="C:\Project\WCFService\Service">
    </server>
  </servers>
</jampad.devServer>

You can also change the binding of each server to allow remote or Virtual PC access for testing purposes.  For full documentation on DevServer see http://www.netfxharmonics.com/2008/04/NetFXHarmonics-DevServer-Released.

For now, though, just know that if you enable tracing as well as verbose tracing, you will see all requests that come into a particular web server, thus allowing you to see if your Silverlight application is even looking for the ClientAccessPolicy.xml file and allowing you to see service messages.  Sometimes you don't want to write a full UI to see what a service is sending and you don't feel like attaching a debugger to look at an object's content.  Using DevServer, you can just look at the raw data the server is sending.  DevServer will automatically format anything it thinks is JSON or XML, allowing you to view it in its pretty form (of course, there's also a raw data view as well).  Here's a screen shot of what I got when I ran the sample for this document:

DevServer

As you can see, this can be tremendously helpful when you need to know how to parse or deserialize the incoming data or even to see if a response is even coming back from the server.

Conclusion

As you can see, there's more to Silverlight connectivity in WCF than the naive "Add Service Reference" option.  By simply understanding the mechanics of what's going on, we are able to tailor a solution to our specific needs.  WCF requires nothing more than an address, a binding, and a contract. With this information we can create a channel to access our service.  Then, with a few changes here and there we can optimize our experience for both security and fault tolerance.  Or, in the case of JSON, we can use tools already provided to us to obtain the exact JSON fields we need.  Hopefully you understand the often hidden concepts of WCF for .NET and Silverlight much better than you did before.

As a quick closing note, if you like going into technology at this level of depth, but also like thorough explanations, you seriously need to check out Juval Lowy's book, Programming WCF (2nd Edition).

Links

kick it on DotNetKicks.com

Silverlight 1.0 Released

September 05, 2007

In case you haven't found out yet, Silverlight 1.0 has officially been released.  Being a JavaScript developer and having been trained in Game Development I find that to be really awesome because Silverlight 1.0 does an amazing job with graphics and video.  However, you probably shouldn't get too excited as this isn't actually the REAL Silverlight we are all waiting for.  The Silverlight that will make people jump for joy is Silverlight 1.1 (I highly expect this to be renamed to Silverlight 1.5 or Silverlight 2.0 before it's released), which should be released sometime in the next year.  Why Silverlight 1.0 is released in such a castrated form is beyond me.  I'm hearing all kinds of Flash experts slam it left and right and every million or so insults they actually get one that's right.  I'm not sure why Microsoft's marketing did it this way, but I'm sure they have an awesome plan for it (the marketing team isn't stupid-- there is a reason it's a multi-billion dollar corporation).  I'm very anxious to see how this marketing tactic works.

As I just mentioned I've been hearing Flash "experts" say all kinds of things about Silverlight and rarely, rarely, rarely are they ever true.  For instance, two days ago I actually heard someone say "...then you have Microsoft's Silverlight and what a piece of junk.  I mean... come on... it doesn't even do video!  How can you expect to compete with Flash when you don't even support video!"  Of course, when you say something with a smile and the right tone, you immediately get people to agree with you.  In reality, however, not only will Silverlight 1.1 support video, Silverlight 1.0 supports video (in all kinds of awesome ways).  Furthermore, video is one of the core features of Silverlight!  In fact, Scott Guthrie over at Microsoft has an awesome blog entry published last night discussing some of the great media intensive features Silverlight brings (he also shows clients actually using Silverlight!)  So, I'm not sure were people get their information (an Adobe forum??) but it's clearly a product of propaganda, not of truth.  Perhaps people should watch demos of a technology and ask a Silverlight expert about the technology before listening to the anti-Microsoft Flash advocate's explanation of their competition.  It's just a thought.  Actually, that idea could go into every area of life.

In one sense Silverlight isn't going to touch Flash.  That is, in the Silverlight 1.0 sense.  This version of Silverlight doesn't do anything but video and graphics.  If you want to do more, you're going to be building your components by creating them from using graphics components.  However, in another sense there is no competition between Silverlight and Flash because of a simple DOA: Flash is Dead On the Arrival of the next Silverlight.  Period.  If you want to do comparisons, then it may be better to compare Silverlight with Adobe Flex.  You can't have a fair comparison between Silverlight and Flash.  That's like comparing Firefox to Internet Explorer.  Firefox is a development integration and web suite where as Internet Explorer is a COM component thrown into a shell application.  Flash does all kinds of awesome animations and graphics, but is slower than even Java (and that's slow!) when it comes to applications whereas Silverlight is WPF for the Web backed by the power and depth of the .NET framework and by CLS languages.  Flash requires that you cough up hundreds of dollars to use an extremely non-intuitive timeline based system whereas Silverlight allows you to use anything from notepad to Visual Studio and follows a much more intuitive event based model (Flash can do events and SilverLight can do timelines, but I'm talking in general).  Furthermore, Silverlight is designed after the XHTML/CSS and WPF model of design and development separation that allows developers to do what they do best and designers to do what they do best at the same time in the same project with no conflicts.  Where as in the XHTML/CSS model, developers create raw XML and designers create CSS designs and in WPF/Silverlight developers breath the life of logic into a solution while the designers are breathing the life of beauty in to it.  One is using Visual Studio and the other is using Expression Blend.  Or one is using Visual Studio Express and the other is using... um... Visual Studio Express.  You don't need expensive tools.

Something I don't think people realize that Silverlight isn't all that new.  It's basically "WPF for the Web".  Personally, I think the naming is kind of weird.  I mean, it seems completely backwards.  WPF/E was the project codename and Silverlight is the product name.  That sounds like the opposite of what Microsoft's naming people usually do.  You would think that Silverlight would be the project codename and that WPF/E or "WPF Web Edition" or something would be the final product name.  It's with the name of Silverlight that people get the idea that Silverlight is a completely new Microsoft technology, when in reality it's simply "WPF for the Web".  You need to learn WPF before you get near Silverlight (unless you just want to be a hacking coder, not a professional) and you really need to learn .NET development before you learn WPF.  It's an incredibly powerful technology that seamlessly fits in with the many other .NET technologies.  If you try to jump into Silverlight without learning WPF you won't have a clue what's going on.  You will be completely confused why the technology even exists and probably go off telling people that Microsoft made a new useless technology simply to take over a new market.  I expect that to be exactly what the Flash people will be doing.  Also, if you try to learn WPF (or ASP.NET or WCF or any other .NET technology) without understanding the fundamentals and paradigms of .NET, you will probably hate those technologies and complain about how hard .NET is to learn or use.  I've seen this before and it's always based on ignorance of .NET or confusion of .NET.  So, if you go to hit up Silverlight, make sure you understand WPF and .NET first.  I don't mean you "did some projects" WPF or .NET.  Your experience has nothing to do with your skill.  Did you study the paradigms and philosophies of .NET and WPF?  Do you understand dependency propertiesRouted eventsXAML? No? Then you need to fulfill the prerequisites first.

Related Links

Moonlight: Mono's Silverlight

June 25, 2007

Here's something rather interesting... the developers on the Mono team "hacked" Silverlight and it only took them 21 days to do it. They are calling their own product "Moonlight", which I have to admit is a much cooler product name than Silverlight.

Project details as well as some internal information including a bit of information about Silverlight internals are are the link below. Even if you care nothing about Mono or Moonlight, if you have any interest in Silverlight at all you should check it out simply for that.

This is actually really cool as it should seriously help promote Silverlight as a de facto standard worldwide, but I doubt anyone will be making a documentary called "21 Days" any time soon.

Silverlight's Adoption as Public De-Facto Standard

June 20, 2007

Recently there have been comments floating around the internet and around conferences that Microsoft's Silverlight needlessly uses XAML as its mark up language where it should have used SVG (Scalable Vector Graphics). The argument here is based on the idea that since SVG is a vector technology accepted in all web browsers except IE, Microsoft should have used it instead of XAML and then simply added support for SVG to IE. While this seams to some to be a valid criticism and a good point to some of the web standards world, it is absolutely groundless and carries no weight.

Silverlight can be viewed as a web extension of the Windows Presentation Foundation (WPF), a .NET 3.0 technology and not simply as a new web technology. As such, it makes sense that Silverlight uses XAML, not SVG. If Silverlight were based on SVG, then there would be a chasm between Silverlight and the .NET Framework, but as it stands Silverlight's use of XAML makes it part of the .NET family. In fact, it’s important to note that elements in XAML usually represent objects in the .NET Framework; this would simply not be possible in SVG. Therefore, by choosing to use XAML over SVG, Microsoft kept SVG pure by not add proprietary technology to it.

Furthermore, SVG is "Scalable Vector Graphics" and as the name suggests it for vector graphics. If Microsoft were to start out with SVG as their base technology they would quick to add UI controls to it thereby altering it making it a Microsoft dialect of SVG, which would not be SVG at all. This would take the entire web world back to the same disasters that were seen in proprietary HTML elements, proprietary CSS selectors and rules, and proprietary JavaScript dynamics (i.e. "DHTML behaviors"). Aside from the architects and developers on the Internet Explorer team, the world, including Microsoft as a whole, thankfully has a lot more respect for specifications and standards than this.

Standards advocates should be very satisfied with Microsoft's decision to start from scratch on this one. Standards, as they are normally referred to as, deal with standardization and thereby allow everyone to talk about the same technology without proprietary terminology or technology. If Microsoft sets an explicit syntax on a well-defined language, publicly states the specification for the language, and makes it a multi-platform language, then the world has basically the same result that a standard would have (this point will be hit again in a moment.) While it's true that "popular" doesn't make things right (something most people learn early in high school) and that statements about "most people" do not mean a single thing, having a well-defined technology set with a set specification does make it a first class technology.

We can see this in the ECMA-334 (C#) specification. Microsoft could have taken JavaScript and forced it to obey the Common Language Specification (CLS) and pawned it off as the primary .NET Language, but they instead chose to create something entirely new and then publicly displayed the specification for it. So when .NET guides are written the samples usually have code for C# and VB, instead of JScript and VB. Those who criticize Microsoft for not using SVG as their client-side technology probably applaud Microsoft for creating a new programming language.

Lastly, it should be noted that one of the primary purposes of using the web as a platform is to make something more accessible. People should be able to use any sufficiently advanced web browser to access a web page or web application anywhere on the entire Internet. Truly, even if an application is created in a corporate environment, if the technologies used are proprietary to any one specific web browser, the primary purpose of using a web browser is defeated and using a smart client would probably give a much richer experience and result. So, while it is true then that the use of proprietary technology, such IE specific content, defeats the entire purpose of using the web as a platform, if a technology is spread enough, is on enough platforms, and allows integration into their current environment (i.e. Firefox, Safari, Opera), it doesn't need to be a standard because it would achieve the same result as a standard. Flash is probably the best example of this.

In conclusion, there should not be much fuss about Microsoft's new "Flash-killer" using what some would view as private corporate technology. As long as there is support for Silverlight in Firefox, Opera, Safari on Windows, Mac OS X, and Linux and a seamless installer experience, there shouldn't be any problem with a rapid world wide adoption of this new technology. Hopefully Silverlight's adoption into the web as a de-facto standard will silence many forms of critisism about it and help prompt developers to do a better job of creating intranet and Internet solutions for muliple platforms and multiple web browsers.

Converting JSON to XAML

April 17, 2007

For reasons beyond human comprehension, the world felt like making an huge deal about Microsoft "revealing" SilverLight even even though WPF/E has been known about for some time now and even though nothing technical has changed even in the slightest with the simple change of a name. Having said that... it will probably be an awesome technology and I'm sure I'll be marinating many of my future applications in it. Editing XAML in notepad is much more appealing to me than being forced to use the overpriced and overly complicated Flash.

As cool as that is, however, since most of the work I do involves pure Ajax/JavaScript clients with almost all .NET coding at the service level, I definitely find JSON (which IS a JavaScript object) easier to manage than XML (which CAN BE a JavaScript object). So, in one of my applications I have the service that provides graphical information to Silverlight in the form of JSON serialized XAML, which will then be converted into XAML.

Here is an example of something the service would provide:

var jsonElement1 = {
        'Ellipse': {
        'Canvas.Left': '130',
        'Canvas.Top': '130',
        Height: '200',
        Width: '200',
        Stroke: 'Red',
        StrokeThickness: '10',
        Fill: 'SlateBlue'
    }
};

No, it's not human readable like XML is, but it's what JavaScript loves to see and it's what my service creates. Also, no, this is done for for efficiently purposes. This doesn't lower the service "message" size in the slightest, but it does however help to keep a consistence programming model across all my service calls. Furthermore, given that the data was in a database and not in XAML on the server, there's no real overhead. If, however, the data was in XAML on the server it would be a sign of pure stupidity for me to convert that to JSON and then back to XAML.

The parsing for something like this is actually really simple: just iterate through the JSON objects and arrays and creating an XML tree from it. As a reminder or reference, with regard to XML in a web browser, Firefox uses document.implementation.createDocument for XML while IE uses the MSXML2.DOMDocument COM object. Furthermore, Firefox is more strict in its usage of XML than the more familiar COM model that IE uses.

Here is an example of what I mean:

var doc = null;
if(DOM.implementation && DOM.implementation.createDocument) {
    doc = DOM.implementation.createDocument('', '', null);
    Xaml.ScanJSONElements(doc, data, doc);


    var xmlSerializer = new XMLSerializer( );
    return xmlSerializer.serializeToString(doc);
}
else {
    doc = new ActiveXObject("MSXML2.DOMDocument");
    Xaml.ScanJSONElements(doc, data, doc);
    return doc.xml;
}

As you look through the Xaml.js file provided, you will also see that Firefox is very explicit about it's namespaces, while the COM model figured you will take care of them. There's nothing wrong with either approach, it's just something you will want to be aware of if you ever create XML in JavaScript.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.

Mini-icons are part of the Silk Icons set of icons at famfamfam.com