2005 2006 2007 2008 2009 2010 2011 2015 2016 2017 2018 aspnet azure csharp debugging docker elasticsearch exceptions firefox javascriptajax linux llblgen mongodb powershell projects python security services silverlight training videos wcf wpf xag xhtmlcss

Learning WinDBG/SOS and Advanced Debugging



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

Silverlight SOS Commands



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

Setting a Silverlight 2 Startup Breakpoint using WinDBG



As I've mentioned on a previous occasion, hardcore debugging is done with WinDBG and SOS.  Visual Studio's debugger just isn't enough for the super interesting scenarios.  I've also mentioned that I have no intention of giving a step-by-step introduction into how to use SOS.  However, given that debugging is directly related to internals and that most people with advanced Silverlight issues will search for "advanced Silverlight debugging" or the like, I'll provide a little information here and there to help people find what they are looking for quicker.

Here I would like to explain how you can set a break point very early in the Silverlight load process, before your application even loads.  This technique will give you a glimpse into the internals of Silverlight to see how things work.  It will also help you to step through your method calls from the very beginning in WinDBG.

First, however, understand that Silverlight has three major components that you need to be aware of:

  • NpCtrl.dll
  • AgCore.dll
  • CoreCLR.dll

Each of these components is critical to loading and running a Silverlight application.  NpCtrl.dll is a browser plugin which follows the Netscape Plugin API (NPAPI).  When your browser sees that you are trying to load Silverlight 2, it will call the NPInitialize export (a public DLL function).  Later, this plug-in will load the AgCore.dll and create a instance of the COM class XcpControl2 to allow NpCtrl to interact with Silverlight (you too can use XcpControl in your COM development).  AgCore is the unmanaged part of Silverlight 2.  It handles everything from DOM interaction, to rendering, to media play.

At this point you will see the spinning XAP-loading progress bar.  When this is complete, NpCtrl will finally load CoreCLR.dll.  Upon load, the DllMain function for this DLL is called.  This function will start up the CoreCLR, the CLR that Silverlight 2 uses.  Upon completion, NpCtrl then calls the GetCLRRuntimeHost DLL export to get the loaded instance of the CLR.  The rest of your application is ready to run (as a side note, the order of a few of these things changes under certain circumstances, so you may actually see CoreCLR load AgCore.)

With this information you're ready to start a fresh instance of a web browser (it's crucial that Silverlight 2 isn't already loaded) and attach WinDBG to your browser's process.  Upon attach you are given control to the command interface.  To set a breakpoint when Silverlight 2 starts, you set a breakpoint when a specific DLL is loaded.  Depending on your needs this may be the npctrl.dll, agcore.dll, or coreclr.dll.

You set a breakpoint for a DLL load in WinDBG by using the following command:

sxe ld:DLLNAME

Thus, if you wanted to break at a specific point in the Silverlight loading procedure, you use one of the following commands:

sxe ld:npctrl

sxe ld:agcore

sxe ld:coreclr

If you want to remove these breakpoints, just type the the following:

sxr

Once you have one or more DLL load breakpoints these and resume your application (the 'g' command or F5 in WinDBG) you can test it our by going to http://themelia.netfxharmonics.com/. If successful, WinDBG will break when your DLL loads.  In the call stack window (or when you type the 'k' command), you will see a call stack that looks something like the following:

kernel32!LoadLibraryW+0x11
npctrl!GetCLRRuntimeHost+0x112
npctrl!CWindowsServices::CreateCLRRuntimeHost+0x19
agcore!CCLRHost::Initialize+0x12a
agcore!CRuntimeHost::Initialize+0x60
agcore!CCoreServices::CLR
Startup+0x95
agcore!CDeployment::Start+0x27
agcore!CCoreServices::StartDeploymentTree+0x53
npctrl!CXcpBrowserHost::put_Source+0x10f
npctrl!CommonBrowserHost::OnGotSourceDownloadResponse+0x4b
npctrl!CXcpDispatcher::OnReentrancyProtectedWindowMessage+0x284
npctrl!CXcpDispatcher::WindowProc+0x51 ¨C11CUSER32!InternalCallWinProc+0x28 ¨C12CUSER32!UserCallWinProcCheckWow+0x150

Chances are, though, that you won't see this information like this at first.  Instead, you will probably see a series of memory addresses.  To view the actual function names, you must configure your symbol paths in WinDBG.  These symbols, often called PDBs, will relate the machine information with information from the original source.  In our case, we need them to view the function names.

To setup symbols, use the following command, replacing C:_SYMBOL with a symbol location of your choice (symbols are very important and, therefore, should not be thrown into a "temp" folder):

. symfix SRVC:_SYMBOLhttp://msdl.microsoft.com/download/symbols;SRVC:_SYMBOLhttp://symbols.mozilla.org/firefox

You may also enter this information in the window that is shown when you hit Ctrl-S.  Either way, this will configure the symbols for both Microsoft's symbol server and Mozilla's.  The latter will help you view exactly how far the loading processing has gone while in Firefox.

With the symbols configured, you will then be able see something like the above call stack.  If you set the symbols after you had already loaded Silverlight 2 in your browser, then you need to exit the browser, start a new instance, and reattach WinDBG.  Regardless, every time a DLL is loaded, WinDBG will automatically access the appropriate Microsoft and Mozilla and download the symbol file for that DLL.  This will take time for every DLL that is to be loaded.  Expect the WinDBG status bar to read BUSY for a long time.  It will only load the symbol for each DLL once.

The method I've just described works perfectly for breaking in WinDBG Firefox and IE.  But, what about Chrome?  Depending on settings, Google Chrome uses either a process-per-tab model or a process-per-site model.  While this flexibility is great for daily use, for debugging we can't have processes bouncing around like jack rabbits on cocaine.  You need a process that you can attach to that won't run away as soon as you use it.  So, to successfully attach WinDBG to Chrome, you should start Chrome up in single process mode.  You do this as follows:

chrome.exe --single-process

At this point, you can attach to Firefox, IE, and Chrome for Silverlight 2 debugging in Silverlight.

Project Sneak Peek



Today I thought I would give a teaser of my latest side project (I'm about a month into it).

Since I'm not a general "business application" developer, but am a specialist in various areas of technology, most of the projects I work on are awesome.  Two of my favorite projects are the Brainbench C# 2.0 exam and the Brainbench C# 2.0 Fundamentals exam, both as the author.  Immediately after finishing the later project, I ended my 2 year long on-and-off consultancy with Brainbench as author and technical editor.

Now, nearly a year later, I've gone on my own (more teasers in Q2 2009):

Which of the following statements regarding a .NET object's sync block index are true?
 
When an ephemeral segment GC occurs, the synch block index contains a pointer to the next object.
If a root is found by a GC, a bit will be enabled in the synch block index.
Constructed objects have the sync block index initialized to a negative value.
Value types have their synch block index set to the value of their location on the stack.
When a monitor lock is entered, the index of a free sync block is recorded in the synch block index.

Silverlight Feature Requests



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.

Obtaining Enumeration Names and Values in Silverlight 2.0



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
    }

<span style="color: blue">public class </span><span style="color: #2b91af">Program
</span>{
    <span style="color: green">//- $Main -//
    </span><span style="color: blue">private static void </span>Main(<span style="color: #2b91af">String</span>[] args)
    {
        <span style="color: green">//+ name
        </span><span style="color: blue">foreach </span>(<span style="color: #2b91af">String </span>name <span style="color: blue">in </span><span style="color: #2b91af">Enum</span>.GetNames(<span style="color: blue">typeof</span>(<span style="color: #2b91af">Component</span>)))
        {
            <span style="color: #2b91af">Console</span>.WriteLine(name);
        }
        <span style="color: green">//+ value
        </span><span style="color: blue">foreach </span>(<span style="color: #2b91af">Object </span>value <span style="color: blue">in </span><span style="color: #2b91af">Enum</span>.GetValues(<span style="color: blue">typeof</span>(<span style="color: #2b91af">Component</span>)))
        {
            <span style="color: #2b91af">Console</span>.WriteLine((<span style="color: #2b91af">Int32</span>)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.

Adding XmlNode to Silverlight



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.

Tip: Quick Reflector Loading for .NET and Silverlight



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.

Exception Handlers for Silverlight 2.0



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);
            <span style="color: blue">return true</span>;
        }
        <span style="color: green">//+ 
        </span><span style="color: blue">return false</span>;
    });
}

}

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.

CitationAttribute for Citing Work



As a researcher, designer, and open-source developer, it's very important to me to both cite the work I reference as well as to be cited appropriately.  Few things are more lame than finding my research some place on CodePlex disguised work different working under someone else's name… or a file from one of my many open-source systems in someone else's project without my copyright information.

To help me keep track of where a file or piece of research came from, I wrote a quick attribute to help keep some of this metadata around: CitationAttribute.  This is in my Themelia Framework and I use it extensively in my projects to keep track of where research and files came from.  Below is an example of how to use the attribute.  Fritz Onion was kind enough to allow me to include his ViewState parser in my work.  Notice the metadata in the attribute:

[Citation("http://www.pluralsight.com/fritz/", Copyright = "Copyright (c) 2008 Fritz Onion", DateUpdated = "03/25/2008")]
public static class ViewStateXmlBuilder
{
    //+ implementation here
}

Here you can see that the reference source is cited as well as the copyright and date the local file was updated with the appropriate version.  Note that this does not replace a file copyright.  I asked Fritz for a complete copyright comment block and he provided that for me.  Above the actual file I include with my Themelia Framework is his actual C# comment stating his actual copyright/disclaimer.

Here's the CitationAttribute as seen in my Themelia Framework:

#region Copyright
//+ Themelia Framework 2.0 - Core Module
//+ Copyright © Jampad Technology, Inc. 2007-2009
//+
//+ This file is a part of the Themelia Framework.
//+ The use and distribution terms for this software are covered by the
//+ Microsoft Permissive License (Ms-PL) which can be found at
//+ http://www.microsoft.com/opensource/licenses.mspx.
#endregion
using System;
//+
namespace Themelia
{
    /// <summary>
    /// Used to signify that a particular type was pulled from a third part project or piece of research.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
    public class CitationAttribute : Attribute
    {
        private readonly String _source;


        //+
        //- @Copyright -//
        /// <summary>
        /// Represents the copyright of the referenced entity.
        /// </summary>
        public String Copyright { get; set; }


        //- @DateUpdated -//
        /// <summary>
        /// Represents the date the local version was updated with the referenced entity.
        /// </summary>
        public String DateUpdated { get; set; }


        //- @DateUpdated -//
        /// <summary>
        /// Represents the 2 (i.e. "en") or 5 (i.e. "en-US") character culture used to format the date (default = en-US)
        /// </summary>
        public String DateCulture { get; set; }


        //- @License -//
        /// <summary>
        /// Represents the license associated with this file (e.g. BSD, MIT, LGPL, Public Domain; default = Custom). This property is not legally binding.  It should only be used as a means of finding the general direction of where to look for the legally binding license.
        /// </summary>
        public String License { get; set; }


        //+
        //- @Ctor -//
        public CitationAttribute(String Source)
        {
            _source = Source;
            //+
            DateCulture = "en-US";
            License = "Custom";
        }
    }
}

There are a few things to notice about this attribute.  First, there is also a property for DateCulture.  This is very important.  Depending on your culture 05 03 2009 or 03 05 2009 may be March 5th.  Second, there's a License property.  In this example, it's "Custom".  As another example, if you were to cite Themelia, you would use "Ms-PL" as your License.  Third, the source is required.  It's not that it absolutely has to be a URL, but it's definitely required nonetheless.

Where should you use this file?  Anywhere you cite someone's research, where you use someone's file, or derive from their work.  This doesn't mean only in places where you copy/paste a class from another person's framework.  This also means in places where you find an article online and you use the research in that article to write your own class.

For example, if you were looking online for a solution to create a solution for getting Silverlight to access the clipboard (the mother of all security breaches, but whatever!) and you find a blog post about that, then when you write your classes to use that, you need to cite the blog post.  If you don't, then you are depriving a future developer from seeing the commentary of that code.  By citing the research with the attribute, you are telling the future reader where to see the research.  In the case of using a someone else's files, the attribute will tell future developer's (and you) where to find the updated version.

Jeff-Prosise's-Silverlight-Tips



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

New Silverlight 3 Features



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:

Temporary Post Used For Theme Detection (30db4683-20e8-488a-ae67-e6ba51e755da - 3bfe001a-32de-4114-a6b4-4005b770f6d7)



This is a temporary post that was not deleted. Please delete this manually. (5c786901-97ff-47f3-b1f4-cb6c7a43fa79 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

NetFXHarmonics Code Annotation Format



If you look at any of my open-source projects or even the Themelia source code, you will see that I use a special type of coding annotation.  The annotation format I designed (based on the designs of Sky Morey at Digital Evolution Group) is intended to maximize code readability and understandability.  The format is NOT a coding standard, but just what it says: an annotation format.

What’s that means?  Essentially when you are reading code you are constantly parsing all the symbols that you see.  Your brain can only work so fast, though, and some things have a higher parsing latency than others.  For example, VB code is incredibly verbose and uses long symbols to representing even the smallest things.  It will use the symbol “Then” where C# will use the symbol “}” (to some it may seem odd to think of a word as a symbol, but that’s all it is—you never read ever letter of a word you know.  If you know the word, your brain treats it as a symbol, not a series of symbols.)  It will also use two different character sets (what we call upper case and lower case) interchangeably, thus ever increasing the latency.  Though C# was designed with extremely low latency in mind, it, like all other languages, still has excess latency.

Thus, my code annotation format comes on the scene to make mental code parsing extremely fast.  It covers everything from how to case comments, when NOT to write comments, when to add metadata to class members, and how to deal with line breaks (the cardinal rule of the format!)  Most importantly, every annotation rule has an extensive commentary explaining why the rule exists and what value it provides in the long run.

Now, as with ALL THINGS EVERYWHERE, when you first start to apply it, it’s going to seem odd and it will slow you down at first.  After time, however, you will become extremely efficient at it and your code readability should dramatically improve.  When this is used in groups, it should seriously lower decrease the time it takes to read and understand the purpose of code.

You can view the NetFXHarmonics Code Annotation Format at http://www.netfxharmonics.com/document/code/format.

Temporary Post Used For Theme Detection (29109673-c834-4229-aac0-f83a31709e36 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)



This is a temporary post that was not deleted. Please delete this manually. (0116dc20-b162-40f3-a802-d48dd098f90a - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

Using the iPod Touch (and iPhone) for In-Depth Bible Study



I’ve been through a lot of different hand-held devices in the past 10 years.  Most of them are absolute garbage.  Some of them are pretty cool.  But, none of them even come close to the iPod Touch.  I use it for so many different purposes and could write a long paper on each of those.  Big screen, easy to use web browser, massively populated app store… and Amazon Kindle support.

One of the primary purposes I use for iPod Touch for is for my Bible Study.  Head over to http://www.netfxharmonics.com/document/iphone/bible to see my explanation (read: sales pitch) of how the iPod can aide anyone is in-depth Bible Study.  Warning: the thing is very image heavy!

Accessing WPF Generated Images Via WCF



As I've said time and time again, WCF is a very streamlined technology. It's not a "web service framework". Rather, it's a "communication extensibility foundation". When it comes to any type of communication, WCF is your go to card. By communication, I'm not talking about one system talking to another. No, I'm talking about any data transfer. In fact, you can easily use WCF as your entry point into the world of WPF image generation.

There are two topics here: generating images with WPF and sending images over WCF. Let’s start with the first of these.

A quick Google search for "RenderTargetBitmap" will give myriad example of using this technique.  For now, here’s one very simple example (actually, RenderTargetBitmap is simple to work with anyways):

System.IO.MemoryStream stream = new System.IO.MemoryStream();
//++ this is a technique to ensure any transformations render correctly
VisualBrush vb = new VisualBrush(CreateVisual(templateName, text, width, height));
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
    dc.DrawRectangle(vb, null, new Rect(new Point(0, 0), new Point(width, height)));
}
//+ render
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(dv);
//+ encode
BitmapEncoder bitmapEncoder = new PngBitmapEncoder();
bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
bitmapEncoder.Save(stream);

In this code we have some WPF elements being created (returned from the CreateVisual method), a wrapper trick to get transformation to render correctly, that being sent to a renderer, the renderer being sent to an encoder, and finally the encoder being saving the data to a stream. With this we can save the data to a file or whatever we want. It's pretty straight-forward.

For completeness, here is the WPF object tree creation:

//- $CreateVisual -//
private Visual CreateVisual(String templateName, String text, Int32 width, Int32 height)
{
    StackPanel stackPanel = new StackPanel();
    stackPanel.Background = new SolidColorBrush(Color.FromRgb(0xff, 0xff, 0xff));
    //+
    TextBlock textBlock = new TextBlock
    {
        Text = text,
        FontSize = 20,
        Foreground = new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0x00))
    };
    textBlock.Effect = new System.Windows.Media.Effects.DropShadowEffect
    {
        Color = Color.FromRgb(0x00, 0x00, 0x00),
        Direction = 320,
        ShadowDepth = 5,
        Opacity = .5
    };
    stackPanel.Children.Add(textBlock);
    stackPanel.Children.Add(new TextBox
    {
        Text = text,
        FontSize = 10,
        Foreground = new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0x00)),
        Effect = textBlock.Effect
    });
    stackPanel.Children.Add(new Button
    {
        Content = text,
        FontSize = 10,
        Foreground = new SolidColorBrush(Color.FromRgb(0xff, 0xff, 0x00)),
        Effect = textBlock.Effect
    });
    stackPanel.Arrange(new Rect(new Point(0, 0), new Point(width, height)));
    //+
    return stackPanel;
}

If you know WPF, this is natural to you. If you don't, well, the code should be fairly self explanatory.

There's not much to the topic of WPF image generation, so let's talk about sending images over WCF.

To do this, you use a standard web-based WCF setup (i.e. using webHttpBinding). So, here's our config:

<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="imageBehavior">
        <webHttp />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <services>
    <service name="ImageCreator.Web.ImageService">
      <endpoint address="" binding="webHttpBinding" behaviorConfiguration="imageBehavior" contract="ImageCreator.Web.IImageService" />
    </service>
  </services>
</system.serviceModel>

Here's our service host (/Image.svc):

<%@ ServiceHost Service="ImageCreator.Web.ImageService" %>

When it comes to the service and operation contract, all you need to know is that you return the image from WCF as a stream.

Let's say that we want to create images that will be used on the web. That is, we will be accessing the images with HTTP GETS (i.e. via direct URLs ).

using System;
using System.ServiceModel;
using System.ServiceModel.Web;
//+
namespace ImageCreator.Web
{
    [ServiceContract(Namespace = Information.Namespace.Image)]
    public interface IImageService
    {
        //- GetImage -//
        [OperationContract, WebGet(UriTemplate = "/GetImage/{templateName}/{text}/{width}/{height}")]
        System.IO.Stream GetImage(String templateName, String text, String width, String height);
    }
}

Here you can see that we are using the WebGet attribute to specify that the web-based WCF service will be using HTTP GET. This attribute is also used to specify the mapping between the URL and the method.

At this point, we can create our service implementation and paste our WPF code in there (the themeName parameter isn't used in this example; it's only there to give you an idea of what you can do.

public System.IO.Stream GetImage(String templateName, String text, String widthString, String heightString)
{
    //+ validate
    Int32 width;
    Int32 height;
    if (!Int32.TryParse(widthString, out width))
    {
        return null;
    }
    if (!Int32.TryParse(heightString, out height))
    {
        return null;
    }
    //+ content-type
    WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";
    //+
    System.IO.MemoryStream stream = new System.IO.MemoryStream();
    //++ this is a technique to ensure any transformations render correctly
    VisualBrush vb = new VisualBrush(CreateVisual(templateName, text, width, height));
    DrawingVisual dv = new DrawingVisual();
    using (DrawingContext dc = dv.RenderOpen())
    {
        dc.DrawRectangle(vb, null, new Rect(new Point(0, 0), new Point(width, height)));
    }
    //+ render
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
    renderTargetBitmap.Render(dv);
    //+ encode
    BitmapEncoder bitmapEncoder = new PngBitmapEncoder();
    bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    bitmapEncoder.Save(stream);
    //+ seek
    stream.Seek(0, System.IO.SeekOrigin.Begin);
    //+
    return stream;
}

With this setup, you have a wonderful system where you can access http://www.tempuri.com/Image.svc/GetImage/skyblue/Close/75/24 and get a beautiful... error.

Why would you get an error? For the simple reason that WCF is a highly threaded monster and WPF only rendered with STA (single thread apartment). Therefore, we need to do something like the following:

public System.IO.Stream GetImage(String themeName, String text, String widthString, String heightString)
{
    //+ validate  
    Int32 width;
    Int32 height;
    if (!Int32.TryParse(widthString, out width))
    {
        return null;
    }
    if (!Int32.TryParse(heightString, out height))
    {
        return null;
    }
    //+ content-type    
    WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";
    //+    
    System.IO.MemoryStream stream = new System.IO.MemoryStream();
    System.ServiceModel.OperationContext context = System.ServiceModel.OperationContext.Current;
    System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
    {
        using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
        {
            //++ this is a technique to ensure any transformations render correctly          
            VisualBrush vb = new VisualBrush(CreateVisual(themeName, text, width, height));
            DrawingVisual dv = new DrawingVisual(); using (DrawingContext dc = dv.RenderOpen())
            {
                dc.DrawRectangle(vb, null, new Rect(new Point(0, 0), new Point(width, height)));
            }
            //+ render       
            RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
            renderTargetBitmap.Render(dv);
            //+ encode   
            BitmapEncoder bitmapEncoder = new PngBitmapEncoder();
            bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
            bitmapEncoder.Save(stream);
        }
    }));
    thread.SetApartmentState(System.Threading.ApartmentState.STA);
    thread.Start();
    thread.Join();
    //+ seek 
    stream.Seek(0, System.IO.SeekOrigin.Begin);
    //+  
    return stream;
}

Now it will actually render. In fact, behold the greatness:

100

While this works fine, it's not idea. When you need to have mechanics stuff next to what you are actually trying to do, you're typically doing something wrong. In this case you have the threading stuff all over the place. This is like tracking mud all over the living room. The mud isn't bad, you just don't want it next to your couch.

To get around this, you can tap into the world of WCF further and create an operation behavior to run the operation as STA. Technically, we don't care about the operation behavior so much as we do the operation invoker we also need to create. We want to control the invocation of the operation.  For this we create an operation invoker; the operation behavior is only there to install the invoker. Let's get to it...

An operation behavior is nothing more than a class that implements the System.ServiceModel.Description.IOperationBehavior interface. Typically it inherits from the System.Attribute class, but this isn't a strict requirement. Doing this does, however, allow the operation behavior to be applied declaratively to your operation implementation. Again, this is optional.

The only method we care about in our new operation behavior is the ApplyDispatchBehavior method. Using this method, we can install our operation invoker. Here's our behavior:

using System;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
//+
namespace Themelia.Web.Behavior
{
    [AttributeUsage(AttributeTargets.Method)]
    public class STAOperationBehavior : Attribute, System.ServiceModel.Description.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 STAInvoker(dispatchOperation.Invoker);
        }


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

Next, let's actually build the operation invoker this guy is installing.

An operation invoker is class which implements the System.ServiceModel.Dispatcher.IOperationInvoker interface. Among other things, the invoker allows us to hijack the WCF process and put our own logic around our operation implementation. This is a VERY useful things to do. For example, whenever I want to implement my own security on services I'll create an invoker to do authorization.  If authorization is successful, I'll call the operation myself. Otherwise, I'll throw a security exception and WCF will deal with it from there.

For our purposes, we are going to use this hijacking ability to starting a new STA thread and call the operation from that thread. We are going to do this in the Invoke method.

using System;
using System.Security;
using System.ServiceModel.Dispatcher;
//+
namespace Themelia.Web.Behavior
{
    public class STAInvoker : System.ServiceModel.Dispatcher.IOperationInvoker
    {
        //- $InnerOperationInvoker -//
        private IOperationInvoker InnerOperationInvoker { get; set; }


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


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


        //- @Invoke -//
        public Object Invoke(Object instance, Object[] inputs, out Object[] outputs)
        {
            Object result = null;
            Object[] staOutputs = null;
            System.ServiceModel.OperationContext context = System.ServiceModel.OperationContext.Current;
            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
            {
                using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
                {
                    result = InnerOperationInvoker.Invoke(instance, inputs, out staOutputs);
                }
            }));
            thread.SetApartmentState(System.Threading.ApartmentState.STA);
            thread.Start();
            thread.Join();
            //+
            outputs = staOutputs;
            //+
            return result;
        }


        //- @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 bool IsSynchronous
        {
            get { return InnerOperationInvoker.IsSynchronous; }
        }
    }
}

If you look closely at the Invoke method, you will see that we are doing essentially the same thing with the thread that we did with the WPF code directly. Now we can remove that mud from our living room and live cleaner.

Notice, though, one major thing you do NOT want to forget: the declaration of the operation scope. If you forget to do this, you will NOT have access to your operation context. You need this because in our operation we are doing the following:

WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";

This tells the person receiving the image the type of the image (otherwise they have to parse the header or just guess). Without the operation scope declaration, we lose this completely.

Anyways, as you can see form the Invoker method, the current operation context is saved and is restored once the new thread has been started.

Now, to finish the job, all we need to do is apply the attribute to our operation (or use another mechanism if you didn't make the behavior an attribute). Here's what our operation looks like now (with the original logic we had):

//- @GetImage -//
[Themelia.Web.Behavior.STAOperationBehavior]
public System.IO.Stream GetImage(String templateName, String text, String widthString, String heightString)
{
    //+ stuff here
}

Now when you access http://www.tempuri.com/Image.svc/GetImage/skyblue/Close/75/24, you get the actual image you wanted to generate.  Thus, once again, WCF provides a very streamlined way of accessing data.

Samples for this document may be accessed from here.

Understanding WCF Faults in Silverlight



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

Contents

Introduction

Regardless of what platform you are working with, you need some mechanism for dealing with errors.  When it comes to using WCF in Silverlight we are all very fortunate to be able to build out solutions on the back of many tried and true techniques for error management. When working in this context, we are dealing with basic SOAP messages (that is, XML) and WCF's abstraction of those messages, neither of which are new to the world.

If you haven't done so already, you should read the first part of this document entitled Understanding WCF Services in Silverlight (here after "previous document").  You may consider this document an appendix to that one.  That document explains WCF and its integration into the world of Silverlight from a very low level. This document extends that one to explain error management in the world of Silverlight 3. Understanding of the previous document is a prerequisite for understanding this one.

SOAP Review

Before we take a look at error management over SOAP services, we will take a moment to review SOAP messaging. SOAP messaging is based on the concept of sending SOAP messages back and forth between client and service. A SOAP message is the package by which a client and a service communicate. Web services (a.k.a. SOAP services) are not "connected" like a chat channel. Instead, they are "disconnected" like an e-mail system. The client sends the service a message and the service, optionally, sends the client message back (depending on if the client requested a message; one way messaging is very common). Below is a sample message sent from a client to the service:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <GetPersonData xmlns="http://www.netfxharmonics.com/service/Contact/2009/07/">
      <personGuid>F488D20B-FC27-4631-9FB9-83AF616AB5A7</personGuid>
    </GetPersonData>
  </s:Body>
</s:Envelope>

Essentially, this message is calling the "GetPersonData" operation on the service, sending "personGuid" as a parameter. This is stored in the message body (which is distinct from, say, a message header, which is not present in this example). The body is then stored in an envelope. When this message is sent via an HTTP POST to, for example, /Person.svc with the SOAP-Action HTTP header set to the name of the SOAP operation, WCF calls the appropriate operation (set by the SOAP-Action HTTP header).  For more information on the mechanics of WCF and how to work with WCF directly see my XmlHttp Service Interop series at http://www.netfxharmonics.com/2007/05/XmlHttp-Service-Interop-Part-3-XML-Serialization).

Here is a message the service could possibly send back to the client:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <GetPersonDataResponse xmlns="http://www.netfxharmonics.com/service/Contact/2008/11/">
      <GetPersonDataResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <City>Unknown</City>
        <FaultDetail i:nil="true" xmlns:a="http://schemas.datacontract.org/2004/07/General.Service"/>
        <FirstName>John</FirstName>
        <Guid>89DEA4C5-84A0-45db-A60D-CE49F214EA50</Guid>
        <LastName>Doe</LastName>
        <PostalCode>66062</PostalCode>
        <State>KS</State>
      </GetPersonDataResult>
    </GetPersonDataResponse>
  </s:Body>
</s:Envelope>

Here we have the data for "GetPersonData" in a result object, wrapped in a response container. This is then, once again, wrapped in a standard SOAP body, inside a standard SOAP envelope. Pretty simple stuff. Someone sends a message, the receiver sends something back. The question now becomes... what happens when something goes wrong?

Handling Errors

When doing error management with SOAP-based WCF, you are doing just that: error management. You are NOT doing exception management. Exceptions don't exist over the wire. How can an exception from WCF being handled by a PHP client? How can System.InvalidOperationException be handled by a Java client? These scenarios make no sense. Therefore, in the world of SOAP services, you have no exceptions. Instead, you have a concept called a "fault".  A fault is a SOAP error.  WCF, Java, and PHP can all deal with SOAP (since SOAP is just XML), thus, they each can deal with faults with no problem. Given this, we may adjust our terminology at this point from "error management" to "fault management".

In reality, a fault is nothing more than a piece of XML formatted in a specific way. One side sends it, the other side receives it. It's a really simple setup. (As a side note, please keep in mind that this is not a document on the internal mechanics of SOAP. That's a discussion for a different document. Fortunately, though, the understanding of faults in SOAP doesn't require deep SOAP knowledge.)

When an exception is thrown in a SOAP-based WCF service, typically a fault is sent over the wire. A SOAP-based client (be it WCF, WCF in Silverlight, PHP, or Java), then obtains it, parses it and handles it accordingly. So what's a SOAP fault look like? (you'll see later that this is an example of a very poor practice, but it's a good fault example.)

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">Really descriptive message here.</faultstring>
      <detail>
        <InvalidOperationException xmlns="http://schemas.datacontract.org/2004/07/System" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema">
          <ClassName i:type="x:string" xmlns="">System.InvalidOperationException</ClassName>
          <Message i:type="x:string" xmlns="">Really descriptive message here.</Message>
          <Data i:nil="true" xmlns=""/>
          <InnerException i:nil="true" xmlns=""/>
          <HelpURL i:nil="true" xmlns=""/>
          <StackTraceString i:nil="true" xmlns=""/>
          <RemoteStackTraceString i:nil="true" xmlns=""/>
          <RemoteStackIndex i:type="x:int" xmlns="">0</RemoteStackIndex>
          <ExceptionMethod i:nil="true" xmlns=""/>
          <HResult i:type="x:int" xmlns="">-2146233079</HResult>
          <Source i:nil="true" xmlns=""/>
        </InvalidOperationException>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope>

Notice that even this fault is a SOAP message: the contents are in a SOAP body, wrapped in a SOAP envelope. So, all we really did is use a concept we already knew and added something to it. By sending a "Fault" XML element in a message body, you are effectively telling the client that some error occurred on the service-side. This is a well-known pattern that all SOAP services follow.

If you look closely at this SOAP message (which, of course, is also a fault), you will notice that the "Fault" element has three children: "faultcode", "faultstring" and "detail". You may recognize some parts of this specific fault.  That is, you see the name "InvalidOperationException" as well as the "Message", "InnerException", and other elements as well-known properties of exceptions. Keep in mind, though, that none of these have anything to do with faults. These are in the "detail" section of the fault, not in any part that actually matters.  Clear as mud?

Faults don't rely on the detail element. The information in this block is simply for the end developer to obtain custom information. Since WCF doesn't rely on this information, neither should you (i.e. it won’t always be there). A fault is defined by the "faultstring" element, not the "detail" element. The "faultstring" element contains is the actually message that you will want to look at when debugging.

Not even the "faultcode" element isn’t directly used by most people. This is a well-defined enumeration with the possible values of "Client", "Server", "VersionMismatch", and "MustUnderstand" (prefixed with the XML namespace). These help you to get some idea of the category of error that occurred, but, in the majority of cases, you won't be working with it directly.  This is all to reinforce the fact that it’s faultstring that contains the actual error, not faultcode or details.

Applying to WCF

In the world of WCF for .NET, all of this is essentially internal mechanics that most mid-level or entry-level developers will only see on a senior-level developer's whiteboard (i.e. they won't use it directly). This is because WCF knows to look for faults and knows how to handle them: it will take the content from faultstring and set that as the Message in a System.ServiceModel.FaultException object. This instance of a FaultException object is developers directly work with.

Now pay attention very closely: you can't just throw an exception in a WCF service and expect it to show up on your client (or to show up over the wire for that matter!) Why is this? Thikn about it... do you really want an exception which contains the entire stack trace and, therefore, a snapshot of the private internal mechanics of your system thrown to a client computer? Obviously not. Since WCF knows is a horrible security violation to send stack traces over the wire, it's not going to allow this.  In fact, that fault SOAP-message shown early is hopefully a picture from fiction, not reality (you kind of figured there were a lot of unneeded xml elements, didn't you?)

What you actually do, is you throw one of two special exceptions: System.ServiceModel.FaultException or System.ServiceModel.FaultException<T> (which inherits from the first one). When you throw an exception which isn't one of these, like System.InvalidOperationException, you will see the following over the wire (i.e. throw new System.InvalidOperationException("This is my error message.")):

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
      <faultstring xml:lang="en-US">The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the &lt;serviceDebug&gt; configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.</faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope>

You may think "not pretty". Trust me, that IS pretty. Ugly would be showing your internal stack trace over the wire. Thank you WCF for protecting us from ourselves.

Now, if you throw System.ServiceModel.FaultException instead of System.InvalidOperationException (i.e. throw new System.ServiceModel.FaultException("This is my error message."), you will see this:

<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 my error message.</faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope>

Very simple and to the point. You told it "This is my error message." and it sent "This is my error message." Can't get much simpler than that.  In fact, the simplicity stays even when you work with the exception on the client side.  Over there, the client will also have a FaultException.  The “faultstring” from the SOAP message will be places into the Message property of the FaultException object on the client.  An example of this will be shown in a bit.

Let's make this a bit more complex (read: more useful/powerful) by changing things up slightly.

As I've said, there are two fault exception types in WCF: one generic, one not. Use of the generic one allows you to send more information to the client by allowing entire objects to be serialized over the wire as part of the fault "detail" element. To see an example of this, take a look at the following custom type:

namespace Contact.Service
{
    [DataContract]
    public class FaultDetail
    {
        //- @ErrorCode -//
        /// <summary>
        /// Custom business-specific error code.
        /// </summary>
        [DataMember]
        public Int32 ErrorCode { get; set; }
        //- @Type -//
        /// <summary>
        /// Specifies the type of error.
        /// </summary>
        [DataMember]
        public String Type { get; set; }
    }
}

Now, instead of throwing the non-generic fault exception, let's throw the generic one, using the above type as the generic parameter. For example:

//- @GetPersonData -//
public Person GetPersonData(String personGuid)
{
    //+ ...validation here...     
    FaultDetail faultDetail = new FaultDetail
    {
        Type = "Validation",
        ErrorCode = 63873928
    };     //+ throw     
    throw new FaultException<FaultDetail>(faultDetail, "Invalid guid.");
    //+ ...more logic here...
}

Given this, we now have this over the wire:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">Invalid guid.</faultstring>
      <detail>
        <FaultDetail xmlns="http://schemas.datacontract.org/2004/07/Contact.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
          <ErrorCode>63873928</ErrorCode>
          <Type>Validation</Type>
        </FaultDetail>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope>

As you can see, using the generic FaultException type, you can send all kinds of stuff over the wire.

Fault Contracts

While this is great for dynamically typed systems (i.e. PHP and JavaScript), we don't yet have a complete solution for strong-typed ones (i.e. .NET). What’s that? Again, think about it: How does the other end know what type is "FaultDetail". Is that ABCCorp.Web.FaultDetail? ABCCorp.Service.FaultDetail? What's the namespace? In what assembly?

To make this happen in .NET, we have to introduce something called a "fault contract". As you recall from the previous document, WCF has service contracts and operation contracts. Fault contracts are just another contract type in the contact family.

These are setup by applying the System.ServiceModel.FaultContractAttribute attribute to various operations of your service contract.  When you apply this attribute, you must tell it what type you would like to allow to be thrown from that specific operation.  This is simply done by giving the constructor of the fault contract attribute to type object of your fault detail type.  For example, below is our operation contract with the fault contract applied.

//- GetPersonData -//
[OperationContract]
[FaultContract(typeof(FaultDetail))]
Person GetPersonData(String personGuid);

If you're following along and paying close attention you should be thinking "How in the WORLD does that help the client? This is on the server! The same SOAP data is going to come over the wire and the client has no more information." Well, as you recall from the previous document, the contracts must be both on the service-side and on the client-side. In the case of .NET, these are the same types since the contracts are in an assembly shared by both client and service (remember, use of the "Add Service Reference" for .NET-to-.NET communication provides ZERO value and only complicates life).

So, if you are doing .NET-to-.NET, your client contract DOES have this and WCF on the client will automatically know to use that spe