got net?

Kevin Hazzard's Brain Spigot

About the author

Welcome to Kevin Hazzard's blog.
E-mail me Send mail

Recent posts

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Fluent XML Parsing Using C#'s Dynamic Type Part 1

Parsing XML documents using a fluent interface is a very compelling idea. Given some simple XML that contains information about books and their authors (see the end of this article for a sample), I'd like to be able to parse it with something like this:

// for brevity, not all of the XML is shown here - use your imagination
string xml = "<books><book><authors>...<authors></book>...</books>";

// create a dynamic XML parser that enables a fluent interface
dynamic dx = new DynamicXml( xml );

// show the last name of the 1st author of the 3rd book
Console.WriteLine( dx.book[2].authors.author[0].name.last );

Being able to use the dot and [] operators to traverse an XML document makes a lot of sense. But how could we write a class that makes this possible for any XML document, no matter what schema it has? The dynamic type in C# opens up some great possibilities in this case. All you need is a class that will handle the member access (dot operator) and indexer access ([] operation) at runtime. Using dynamic typing in C#, these things can be late-bound, so if a class like the one called DynamicXML in this example existed to do the actual XML parsing, it could make XML handling much simpler and more intuitive. For reference purposes, the full XML sample that we'll be working with is shown at the end of this article.

The source code for my DynamicXml class follows. Now, be warned, I've deliberately left all of the error handling code out of this version. In a subsequent article, I'll add some robustness to the DynamicXml class along with some other dynamic goodies. Scroll down to get a complete analysis of what this class does.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Dynamic;
using System.Xml.Linq;
using System.Collections;

public class DynamicXml : DynamicObject, IEnumerable
{
    private readonly List<XElement> _elements;

    public DynamicXml( string text )
    {
        var doc = XDocument.Parse( text );
        _elements = new List<XElement> { doc.Root };
    }

    protected DynamicXml( XElement element )
    {
        _elements = new List<XElement> { element };
    }

    protected DynamicXml( IEnumerable<XElement> elements )
    {
        _elements = new List<XElement>( elements );
    }

    public override bool TryGetMember(
        GetMemberBinder binder, out object result )
    {
        result = null;
        if (binder.Name == "Value")
            result = _elements[0].Value;
        else if (binder.Name == "Count")
            result = _elements.Count;
        else
        {
            var attr = _elements[0].Attribute(
                XName.Get(binder.Name ) );
            if (attr != null)
                result = attr;
            else
            {
                var items = _elements.Descendants(
                    XName.Get(binder.Name ) );
                if (items == null || items.Count() == 0)
                    return false;
                result = new DynamicXml( items );
            }
        }
        return true;
    }

    public override bool TryGetIndex( GetIndexBinder binder,
        object[] indexes, out object result )
    {
        int ndx = (int)indexes[0];
        result = new DynamicXml( _elements[ndx] );
        return true;
    }

    public IEnumerator GetEnumerator()
    {
        foreach (var element in _elements)
            yield return new DynamicXml( element );
    }
}

OK, let's analyze the DynamicXml class section by section. First of all, notice the inclusion of the new System.Dynamic namespace. This is where the base class called DynamicObject comes from. The DynamicObject class wraps up a lot of the messy details that you would have to take care of if you were writing an implementation of the IDynamicMetaObjectProvider interface. This is an interface that the runtime binder looks for when applying special treatment to dynamically typed objects. Since the DynamicObject class provides an implementation of that interface, using it as a base class for our DynamicXml class does most of the work for us.

Now scan down into the class and notice the TryGetMember and TryGetIndex overrides in the DynamicXml class. The DynamicObject base class provides virtual methods for the various Dynamic Language Runtime (DLR) "verbs" that we want to implement. The DLR uses these verbs to define the border between languages with the common operations that we need to communicate. For example, here are some of the operations that the DLR defines:

  • InvokeMember - call a method
  • GetMember - call the accessor for a property
  • SetMember - call the mutator for a property
  • CreateInstance - this one's pretty self-explanatory; think C#'s new operator
  • GetIndex - when treating the object like a collection, get the element at a specific index
  • SetIndex - set the element at a specific index

Remember that I said earlier that if you wanted a fluent interface for parsing an XML document, you would need to handle the member access (using the dot operator) and index access (using C#'s [ and ] subscripting syntax). Well, these two overrides, TryGetMember and TryGetIndex provide just the implementations we're interested in. So, when the runtime binder accesses members and indexes on a DynamicXml object, it will be routed to these methods. Let's start with the TryGetMember method.

public override bool TryGetMember(
    GetMemberBinder binder, out object result )
{
    result = null;
    if (binder.Name == "Value")
        result = _elements[0].Value;
    else if (binder.Name == "Count")
        result = _elements.Count;
    else
    {
        var attr = _elements[0].Attribute(
            XName.Get( binder.Name ));
        if (attr != null)
            result = attr;
        else
        {
            var items = _elements.Descendants(
                XName.Get( binder.Name ) );
            if (items == null || items.Count() == 0)
                return false;
            result = new DynamicXml( items );
        }
    }
    return true;
}

In a sense, the DynamicXml class is just a facade for a List<XElement> as you can see in the class's declaration. That list is managed in a field called _elements. The TryGetMember override processes requests to access the XElement objects in _elements in a certain order. First, it looks for requests to the Value and Count members. The Count member comes straight off of the _elements list. But the Value member is assumed to be the Value of the first XElement in the list. This is because sometimes, we want the fluent interface to be dealing with a single XML element and other times we want it to be expressing array-like access using the [ and ] symbols. Next, the TryGetMember function gives preference to attributes that may exist in the XML. This is just a design choice. We could have chosen to process child elements before the attributes of the current one instead. If an XML attribute is found by the name that the runtime binder is seeking, it will be returned.

This is an interesting point that you should stop to reflect on. When a dynamic object returns a non-dynamic object, the result is still considered dynamic because the runtime binder is controlling the execution. One way to think of the runtime binder is that it's like late compilation. Even if a statically typed object like an XAttribute is returned, accesses into that object are handled by the runtime binder. Since the XAttribute is not a dynamic type, the C#-specific binder would be used to find and invoke it's Value property, most likely through some type of reflection. So, it's OK to return non-dynamic objects in a dynamic "pipeline". You can even switch back and forth if you desire. The first object in the dynamic chain could return a non-dynamic object, which could return a dynamic object that, through the next invocation, returns a non-dynamic object, etc. The point is that once you start using the dynamic runtime binder, you'll keep using is until the call chain is complete. You should think long and hard about the performance impact that might have on your applications. Runtime binding is slower than the static, compile-time binding that you are accustomed to. There are things we can do to make runtime binding faster but that's a story for another day.

To finish up with describing how TryGetMember works, the XML Descendents of the current element are queried by the name presented by the runtime binder in it's Name property. The resulting iterator is used to create a new instance of the DynamicXml type which is returned from the member access. The reason we must always treat the result as a list is that we can't tell from the source XML if the member being sought is supposed to be a single element or a collection. If we had an XML Schema Definition for the source document, perhaps we could make an optimization for the single instance cases. But this code works OK. Now on to the much simpler TryGetIndex implementation.

public override bool TryGetIndex( GetIndexBinder binder,
    object[] indexes, out object result )
{
    int ndx = (int)indexes[0];
    result = new DynamicXml( _elements[ndx] );
    return true;
}

Now, let's look at TryGetIndex override. It's very simple by comparison to TryGetMember. It expects the indexing type to be a single dimension integer. So it performs that cast then passes the index to the _elements list to create (you guessed it) another DynamicXml object. In this case, a special constructor does the work of converting that single element into a list for reasons described above.

public IEnumerator GetEnumerator()
{
    foreach (var element in _elements)
        yield return new DynamicXml( element );
}

The last important thing to understand is the implementation of IEnumerable. In those cases when the DynamicXml instance is acting like a collection of elements, we would like to be able to enumerate over them. However, internally, the DynamicXml manages XElements which are not, by definition, dynamic. During the iteration of XML in our fluent interface, we want to be able to continue being fluent. To do that, the iterator has to return not XElement objects but DynamicXml objects. So, the enumerator yields each XElement by instantiating a DynamicXml wrapper around it.

You may be asking why I didn't implement strongly-typed enumeration using IEnumerable<DynamicXml> instead. The reason for that is simple. In a dynamic processing context, types get thrown out the window, so to speak. We could implement strong typing but it wouldn't usually matter because iteration that yields DynamicXml types is probably already using the dynamic runtime binder anyhow. For the XML document below, here's a snippet of C# code that parses the entire document using our dynamic, fluent interface.

// the variable xml contains the string text of an XML document
dynamic dx = new DynamicXml(xml);
Console.WriteLine("PublicationDate='{0}'", dx.pubdate.Value);
Console.WriteLine("BookCount='{0}'", dx.book.Count);
foreach (dynamic b in dx.book)
{
    Console.WriteLine("----- Begin Book -----");
    Console.WriteLine("Price='{0}'", b.price.Value);
    Console.WriteLine("Title='{0}'", b.title.Value);
    Console.WriteLine("AuthorCount='{0}'", b.authors.author.Count);
    foreach (dynamic a in b.authors.author)
    {
        Console.WriteLine("   ---- Begin Author ----");
        Console.WriteLine("   EmailAddress='{0}'", a.email.address.Value);
        Console.WriteLine("   FirstName='{0}'", a.name.first.Value);
        Console.WriteLine("   MiddleName='{0}'", a.name.middle.Value);
        Console.WriteLine("   LastName='{0}'", a.name.last.Value);
        Console.WriteLine("   ----- End Author -----");
    }
    Console.WriteLine("------ End Book ------");
}

This code parses the XML fluently and produces the following output from the sample XML below:

PublicationDate='2009-05-20'
BookCount='3'
----- Begin Book -----
Price='45.99'
Title='Open Heart Surgery for Dummies'
AuthorCount='1'
   ---- Begin Author ----
   EmailAddress='mort@surgery.com'
   FirstName='Mortimer'
   MiddleName='Q.'
   LastName='Snerdly'
   ----- End Author -----
------ End Book ------
----- Begin Book -----
Price='32.75'
Title='Skydiving on a Budget'
AuthorCount='2'
   ---- Begin Author ----
   EmailAddress='tfreefall@jump.com'
   FirstName='Trudy'
   MiddleName='L.'
   LastName='Freefall'
   ----- End Author -----
   ---- Begin Author ----
   EmailAddress='bernie@airborne.com'
   FirstName='Bernard'
   MiddleName='M.'
   LastName='Fallson'
   ----- End Author -----
------ End Book ------
----- Begin Book -----
Price='22.40'
Title='How to Dismantle a Bomb'
AuthorCount='1'
   ---- Begin Author ----
   EmailAddress='bono@u2.com'
   FirstName='Bono'
   MiddleName=''
   LastName='Vox'
   ----- End Author -----
------ End Book ------


 <books pubdate="2009-05-20">
  <book price="45.99" title="Open Heart Surgery for Dummies">
    <id isbn10="4389880339"/>
    <authors>
      <author>
        <name>
          <first>Mortimer</first>
          <middle>Q.</middle>
          <last>Snerdly</last>
        </name>
        <email address="mort@surgery.com"/>
      </author>
    </authors>
  </book>
  <book price="32.75" title="Skydiving on a Budget">
    <id isbn="2129034454"/>
    <authors>
      <author>
        <name>
          <first>Trudy</first>
          <middle>L.</middle>
          <last>Freefall</last>
        </name>
        <email address="tfreefall@jump.com"/>
      </author>
      <author>
        <name>
          <first>Bernard</first>
          <middle>M.</middle>
          <last>Fallson</last>
        </name>
        <email address="bernie@airborne.com"/>
      </author>
    </authors>
  </book>
  <book price="22.40" title="How to Dismantle a Bomb">
    <authors>
      <author>
        <name>
          <first>Bono</first>
          <middle/>
          <last>Vox</last>
        </name>
        <email address="bono@u2.com"/>
      </author>
    </authors>
  </book>
</books>

 


Tags: ,
Categories: C# | CapTech
Posted by kevin on Friday, May 22, 2009 8:00 AM
Permalink | Comments (0) | Post RSSRSS comment feed

C#'s Dynamic Type is NOT Just an Object

Consider the following C# 4 code that creates a null dynamic field and a null object field, then attempts to invoke GetType() through each:

using System;

public class Program
{
    private dynamic i;
    private object j;
    public static void Main()
    {
        var app = new Program();
        try { Console.WriteLine(app.i.GetType()); }
        catch (Exception e)
        {
            Console.WriteLine("{0} says:\r\n\t{1}",
                e.GetType(), e.Message);
        }
        try { Console.WriteLine(app.j.GetType()); }
        catch (Exception e)
        {
            Console.WriteLine("{0} says:\r\n\t{1}",
                e.GetType(), e.Message);
        }
        Console.ReadLine();
    }
}

The console output of this small program is the following text:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException says:
        Cannot perform runtime binding on a null reference
System.NullReferenceException says:
        Object reference not set to an instance of an object.

Why the different treatment between objects and dynamics? After all, we hear all the time that the new dynamic type in C# 4 is really just an object with special runtime behaviors ascribed to it. But the difference in the exception types makes it clear that dynamic types are not plain, old object references. The IL for this code makes it very clear what's going on. I've included the disassembled IL for Main generated by the ILDASM tool below. You'll see that the dynamic field is really a CallSite object. The CallSite class does a lot of interesting things which I'll be blogging about now that the VS2010 Beta 1 is publicly available.

Even if you don't understand what the following code is doing, find the first try block in the code and compare it to the second one. You can see in the second try block that the access to the plain, old object field is very straightforward, just a couple of lines of code. Since the object reference is initialized to null, when the GetType() method is invoked through it, a NullReferenceException is thrown. Standard stuff since .NET 1.0. But in the first try block, where the dynamic field is used to invoke GetType(), the call is dispatched through a compile-time constructed CallSite. So, the CallSite reference is not null which is why we don't get a NullReferenceException. Instead, the CallSite attempts to bind to a real object to dispatch the call and finds that there is nothing there. Hence, the RuntimeBinderException. I think it's important to know that dynamics are not just objects with special runtime behaviors attached to them. I know the following IL code is long and ugly but do this: search in the following text for the word GetType in double quotes. Look at how that string is being passed to the runtime binder in the dynamic case. This is very much like using eval() in JavaScript to inject strings of code into the browser at runtime. C# 4 truly is a dynamic language now.

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       283 (0x11b)
  .maxstack  12
  .locals init ([0] class Program app,
           [1] class [mscorlib]System.Exception e,
           [2] class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000)
  IL_0000:  nop
  IL_0001:  newobj     instance void Program::.ctor()
  IL_0006:  stloc.0
  .try
  {
    IL_0007:  nop
    IL_0008:  ldsfld     class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> Program/'<Main>o__SiteContainer0'::'<>p__Site1'
    IL_000d:  brtrue.s   IL_004e
    IL_000f:  ldc.i4.0

<snip/>

    IL_006c:  brtrue.s   IL_00a2
    IL_006e:  ldc.i4.0
    IL_006f:  ldstr      "GetType"
    IL_0074:  ldtoken    Program
    IL_0079:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
    IL_007e:  ldnull
    IL_007f:  ldc.i4.1
    IL_0080:  newarr     [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo

<snip/>

    IL_00df:  leave.s    IL_00e1
  }  // end handler
  IL_00e1:  nop
  .try
  {
    IL_00e2:  nop
    IL_00e3:  ldloc.0
    IL_00e4:  ldfld      object Program::j
    IL_00e9:  callvirt   instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
    IL_00ee:  call       void [mscorlib]System.Console::WriteLine(object)

<snip/>

  IL_0119:  pop
  IL_011a:  ret
} // end of method Program::Main


Tags:
Categories: C#
Posted by kevin on Thursday, May 21, 2009 7:16 AM
Permalink | Comments (7) | Post RSSRSS comment feed

Service Toggler Source Code

I'm very active in the User Group community so I do a lot of presentations. I wrote a quick and dirty application called ToggleService which lets me start or stop a Windows Service in a visual way. The picture above shows three screen shots side by side. On the left, you see my application as it queries the service called SQL Server (KATMAI) in the stopped state as indicated by the red light bulb. After clicking the Start button, the state transitions which shows the middle screen with the yellow light bulb. After a few seconds the service goes into the started state as indicated by the green light bulb on the right. I wrote this application to give my User Group attendees some visual feedback whenever I needed to start or stop a service during a presentation. It's very effective for that. So effective, in fact, that many people have asked me for the source code.

One important note: when you create a shortcut for this application, you must pass the long or short name of the service to ToggleService.exe on the command line. You can see the long service names in the Services Control Panel applet. In the case of the screen shot above, I found "SQL Server (KATMAI)" as the long name and passed it to the ToggleService.exe application on the command line. To find the short name of a service, you can use the command line service controller like this:

sc \\machineName GetKeyName "SQL Server (KATMAI)"

Of course, you must substitute your own machine name and the long name of the service that your querying for. This will produce output something like this:

C:\>sc \\machineName GetKeyName "SQL Server (KATMAI)"
[SC] GetServiceKeyName SUCCESS
Name = MSSQL$KATMAI

So, to toggle the SQL Server instance on my computer in which I'm interested, I could pass either of the following arguments to ToggleService.exe:

  • "SQL Server (KATMAI)"
  • MSSQL$KATMAI

You might observe at this point that the SC.EXE utility which I used to discover the short name of my service could have been used to start and stop the service during my presentations. Yes, that's true. But the little GUI I built is more colorful and exciting. You have to sell the sizzle and the steak, right? Anyway, the C# source code attached below requires Visual Studio 2008. There's nothing special about it but since so many people have asked for it, I thought I'd oblige. Enjoy!

Source code for Kevin Hazzard's ToggleService Utility (26.73 kb)


Tags:
Categories: C# | Fun | Pres Skills
Posted by kevin on Sunday, May 17, 2009 10:05 PM
Permalink | Comments (1) | Post RSSRSS comment feed

JavaScript Object Notation (JSON) in .NET Part 4

Welcome to Part 4 of a multi-part series on JavaScript Object Notation (JSON) support in the Microsoft .NET Framework. In this article, we'll focus on the JavaScriptConverter class from the System.Web.Script.Serialization namespace. You can find the other parts of this series at these locations:

  • Part 1 - An exploration of the DataContractJsonSerializer class
  • Part 2 - An exploration of the JavaScriptSerializer class
  • Part 3 - JSON serialization from WCF (including a REST primer)
  • Part 4 - Using the JavaScriptConverter class to customize JSON serialization

Welcome back. We've been exploring the differences in .NET's two competing JSON serialization classes for a while now. This time, let's dig into ways that we can customize the JavaScriptSerializer to solve some difficult problems. In some circumstances, the services provided by the JavaScriptSerializer for dehydrating and rehydrating of POCOs just isn't sufficient. As discussed in Part 2 of this series, the JavaScriptSerializer has the interesting capability of handling plain .NET classes that aren't marked up with serialization-related metadata in any way. Most of the competing serialization and deserialization classes in the .NET Framework Class Library require some kind of meadata, typically in the form of attributes, to assist the serializer in doing it's job. And there's good reason for this. Sometimes, simply iterating over the properties and fields of an object doesn't provide enough information to properly put it into a format that's suitable for storage or for transmission. For example, look at the following class definition which uses two properties to expose a single DateTime object in different formats:

public class Redundant
{
    private DateTime _ts = DateTime.Now;

    public Redundant()
    {
        _ts = DateTime.Now;
    }

    public Redundant( DateTime ts )
    {
        _ts = ts;
    }

    public string AsRFC1123
    {
        // return the date in RFC 1123 format
        get { return _ts.ToString( "R" ); }
    }

    public string AsSortable
    {
        // return the date in a sortable format
        get { return _ts.ToString( "s" ); }
    }
}

When an instance of this class is serialized to JSON using the JavaScriptSerializer, it may look something like this:

{"AsRFC1123":"Sun, 17 May 2009 01:00:00 GMT","AsSortable":"2009-05-17T01:00:00"}

As you can see, the serializer decided to include both string properties, AsRFC1123 and AsSortable which is redundant. There's no need to include the DateTime information twice. However, the JavaScriptSerializer can't know what should and should not be serialized because the definition of the Redundant class has no markup to give it clues about what should be included. The JavaScriptSerializer doesn't depend on attributes as some other .NET serializers do. Instead, if you want to customize the serialization process when using the JavaScriptSerializer, you must provide an instance of a class derived from JavaScriptConverter. For the Redundant class, the following converter can be used to fix the problem:

private class RedundantConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        // register the Redundant type
        get { return new[] { typeof( Redundant ) }; }
    }

    public override IDictionary<string, object> Serialize(
        object obj, JavaScriptSerializer serializer )
    {
        // convert the object obj into a dictionary
        // of name value pairs
        var r = obj as Redundant;
        if (r == null) return null;
        var map = new Dictionary<string, object>();
        map["ts"] = r.AsSortable;
        return map;
    }

    public override object Deserialize(
        IDictionary<string, object> map,
        Type type, JavaScriptSerializer serializer )
    {
        // read the name value pairs in the
        // dictionary and rehydrate an instance
        DateTime ts;
        if (DateTime.TryParse( map["ts"].ToString(), out ts ))
            return new Redundant( ts );
        return null;
    }
}

First of all, notice that there are 3 members from the abstract base class that need to be overridden. These are:

  • IEnumerable<Type> SupportedTypes { get; }
  • IDictionary<string, object> Serialize( object obj, JavaScriptSerializer serializer );
  • object Deserialize( IDictionary<string, object> map, Type type, JavaScriptSerializer serializer );
The SupportedTypes property tell the serializer which types the converter supports. In this case, only the Redundant class is handled. The Serialize method accepts an instance of the invoking serializer and the object to be converted into JSON. However, the converter doesn't actually produce JSON output. Instead, the Serialize method on the converter must return a dictionary that maps strings, the names of the members, to objects, the actual objects that will be included. In the RedundantConverter class, you can see that were only including one property to be serialized named "ts". Remember, the whole point of attaching custom serialization is because the AsRFC1123 and AsSortable are redundant. We don't need both of them. And since, we'll only be including one of them (AsSortable), we took the opportunity to shorten the name to "ts". This will make the resulting JSON more compact which is almost always a good idea. The Deserialize method works in reverse, accepting a dictionary of name value pairs and constructing a new Redundant object from it. In this case, the Type parameter of the Deserialize method isn't used because this converter only assists with the Redundant type. However, if multiple types were converted by this class, you could include a switch statement to instantiate the appropriate type based on the Type parameter. Here's a bit of code that registers a RedundantConverter and tests the serialization and deserialization processes:

private static void JavaScriptConverterTests()
{
    var r = new Redundant();
    var jser = new JavaScriptSerializer();
    var rs = jser.Serialize( r );
    Console.WriteLine( "Redundant serialized with" +
        "out conversion support: '{0}'", rs );
    jser.RegisterConverters(
        new JavaScriptConverter[]
        {
            new RedundantConverter()
        } );
    rs = jser.Serialize( r );
    Console.WriteLine( "Redundant serialized with " +
        "conversion support: '{0}'", rs );
    r = jser.Deserialize<Redundant>( rs );
    Console.WriteLine("Redundant deserialized with " +
        "conversion support: AsRFC1123 = '{0}', " +
        "AsSortable = '{1}'", r.AsRFC1123,
        r.AsSortable );
}

The output of this code will look something like this:

Redundant serialized without conversion support:
"{"AsRFC1123":"Sun, 17 May 2009 01:00:00 GMT",
"AsSortable":"2009-05-17T01:06:21"}"

Redundant serialized with conversion support:
"{"ts":"2009-05-17T01:00:00"}"

Redundant deserialized with conversion support:
AsRFC1123 = "Sun, 17 May 2009 01:00:00 GMT",
AsSortable = "2009-05-17T01:00:00"

In closing, let me make one more key observation. Serialization requires that you can get the property values from an object. Deserialization requires that you can set the property values of an object. But notice that the Redundant class has no mutators (set handlers) on its properties. However, since we're doing custom conversion using the RedundantConverter class, that doesn't matter. The converter's Deserialize method simply uses a custom constructor to inject the DateTime value rather than using properties to do it. Yet another really cool thing that the JavaScriptSerializer can do that baffles the average competing serializer class.

That's all for now. Join me next time as we look at how to consume JSON-encoded content in a Silverlight control. Enjoy!


Categories: Architecture | C# | CapTech
Posted by kevin on Saturday, May 16, 2009 9:30 PM
Permalink | Comments (0) | Post RSSRSS comment feed

JavaScript Object Notation (JSON) in .NET Part 3

Welcome to Part 3 of a multi-part series on JavaScript Object Notation (JSON) support in the Microsoft .NET Framework. In this article, we'll focus on performing JSON serialization from a RESTful WCF web service. You can find the other parts of this series at these locations:

  • Part 1 - An exploration of the DataContractJsonSerializer class
  • Part 2 - An exploration of the JavaScriptSerializer class
  • Part 3 - JSON serialization from WCF (including a REST primer)
  • Part 4 - Using the JavaScriptConverter class to customize JSON serialization

Welcome back. In Part 1 of this series, we looked at using the DataContractJsonSerializer to dehydrate and rehydrate .NET classes to and from JavaScript Object Notation (JSON), respectively. In Part 2, we looked at the once rogue JavaScriptSerializer class which has the unique capability of being able to serialize Plain Old CLR Objects (POCO) that aren't marked as [Serializable] or [DataContract]. In this article, we'll focus on something a bit less academic: building a RESTful web service with Windows Communication Foundation (WCF) that delivers JSON encoded objects to its clients.

A Representational State Transfer (REST) Primer

Let's do a little rundown of what Representational State Transfer (REST) means. Like any architectural pattern, REST has some tenets or guidelines for describing what it hopes to accomplish and, in some sense, how it prefers for the work to be done. The REST principles1 for application development are:

  1. Application state and functionality are abstracted into resources
  2. Every resource is uniquely addressable using a universal syntax for use in hypermedia links
  3. All resources share a uniform interface for the transfer of state between client and resource, consisting of:
    • A constrained set of well-defined operations
    • A constrained set of content types, optionally supporting code on demand
  4. A protocol which is client-server, stateless, cacheable and layered

We don't need to cover all of these but there are a couple of high points to take note of. Most people interpret the phrase universal syntax in the second principle to mean that URLs are to be used to address application resources. And that's usually true. Here's the resource identifier for my Twitter.com timeline, for example:

    http://twitter.com/statuses/user_timeline/KevinHazzard.xml

If you click that link, you'll get an XML document that contains the state of my status updates to Twitter.com. The term for this kind of output is Plain Old XML or POX for short. If you change the extension of the resource identifier from xml to json in the URL shown above, what do you think you'll get? That's right. You'll see my Twitter.com timeline in JSON format. Pretty cool, huh? You can learn more about the RESTful Twitter Application Programming Interface (API) if you're interested.

The key word in that second principle is uniquely. What it means is that the resource identifier for the application state of my user timeline on Twitter.com must be different from all the other resource identifiers. Perhaps it's stating the obvious but from an addressing standpoint, REST tends to refer to application state and functionality like a file system. Bits of application state and the functions that an application performs are like a set of files. If you open a file by a well-known name, you'll get the functionality or state that's inside the file. This, of course, helps to define what the first and third REST principles mean, too. In the RESTful URL above, the well-defined operation is not KevinHazzard.xml. That's an argument or parameter, if you will. The operation is user_timeline and, reading left to right, you might guess that it's inside a module called statuses. It doesn't mean that the Ruby code that Twitter.com uses to implement the service is organized that way. But the resources in that class have a constraint that they use to provide a set of uniquely addressable resources.

The sub-bullets of the third REST principle are really interesting to me. One of the complaints about the Simple Object Access Protocol (SOAP) that some web services use is that it's much too rigid to be useful for web application development. Web developers complain that they don't have a Software Development Life Cycle (SDLC) that allows them to digest Web Service Description Language (WSDL) contracts, generate proxy classes and re-compile their code to use the well-defined operations and content types that a web service might provide. But I see through the compaints and the dissatisfaction with SOAP and the SDLC it engenders. The heart of the complaints really have more to do with the fact that great tools for building SOAP clients are rare. Case in point: over the years, I've demonstrated various ways to call SOAP services from environments that don't have great web service support built in. In an article I wrote about invoking SOAP web service from a dynamic language like Windows PowerShell, I demonstrated that WSDL contracts can be consumed at runtime to create and call proxies to SOAP services on the fly. To do that, I had to write a class called WSDLHelper that performs dynamic code generation. Not simple stuff but it works beautifully, making access to SOAP-based services just as easy as calling RESTful services from PowerShell or Python, for example. So, it's not that SOAP is bad, per se. But the tools to make SOAP client development aren't all that great, even in some .NET contexts.

Those sub-bullets of the third REST principle speak to the desire to constrain and define the operations and the data types that flow to and from the service. Without some contraints, the experience of using a RESTful service would be chaotic and unpredictable. Services like Twitter.com have very detailed definitions for their RESTful resources outlined in the Twitter API. It defines the resources (operation contracts), the parameters, the authentication mechanism and the output schema (data contracts) for each resource. Well, that's no different than what SOAP and WSDL are attempting to describe. The fundamental difference, though, is that SOAP and WSDL have rigid and quite rich XML schema definitions for all of that, not just the output of each resource. So, when people say that they dislike SOAP because it's too complex or bulky, look through the veil and understand that they really only dislike parsing WSDL, generating proxies, recompiling code, etc. It's OK to dislike those things, but now that you've read my blog, you understand that if better SOAP client tools existed on more platforms, it would often be preferred due to the richness and type safety that it can lend to the design process.

RESTful WCF

OK, enough about REST principles. Let's look at what it takes to expose a RESTful service in WCF. There are a handful of simple steps you can follow to do this. Assuming that you're going to be using Internet Information Server (IIS) to expose your service, follow these steps:

  1. Add a reference to System.ServiceModel.Web to your web application. This assembly includes the implementations of the WebServiceHostFactory and the WebGetAttribute that you'll be using in the next steps.
  2. In your Web.config file, modify an existing endpoint or add a new endpoint that uses the webHttpBinding binding type. This binding tells WCF that we're going to use HTTP URLs to parse resource identifiers and parameters. It also makes it possible to use RESTful response formats like POX or JSON instead of generating SOAP envelopes to go back to the client.
  3. In the SVC file for the WCF service, modify the <@ ServiceHost> element to include the attribute Factory="System.ServiceModel.Activation.WebServiceHostFactory". This factory class provides instances of the WebServiceHost class to handle the parsing of incoming RESTful URLs.
  4. The last thing you need to do is mark each [OperationContract] that you want to act as a REST resource with the [WebGetAttribute] or the [WebInvokeAttribute]. This is where we'll provide a template that maps incoming URLs to specific operations. These attributes also allow us to map parameters from the URLs to each operation's parameters.

Here's some example code and configuration for my ThingySearchService. Let's start with the [DataContract] and the [ServiceContract]:

using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.Serialization;

[DataContract]
public class Thingy
{
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public int Age { get; set; }
}

[ServiceContract(Namespace = "gotnet.biz:JsonPlay")]
public interface IThingySearchService
{
    [OperationContract]
    [WebGet(UriTemplate = "FindThingy?age={age}&name={name}")]
    Thingy FindThingy(int age, string name);
}

First of all, notice that the [DataContract] attribute is explicitly applied to the Thingy class and that each property is marked with a [DataMember] attribute. The serializers used by WCF to render POX and JSON require this. You could alternatively mark the Thingy class with the [Serializable] attribute but as we saw in Part 1 of this series, the DataContractJsonSerializer often does a better job when the [DataContract] attribute is used instead. The UriTemplate of the [WebGet] attribute tells the WebHostFactory that when URLs referencing the FindThingy resource identifier are encountered, they should be routed here to the FindThingy operation. In addition, the UriTemplate instructs the WebHostFactory how to map the parameters in the URL to the underlying method's parameters. For my ThingySearchService, the following URL:

    http://localhost:51976/ThingySearch.svc/FindThingy?name=Kevin&age=44

might render this XML:


<Thingy xmlns="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

  <Age>44</Age>

  <ID>1682</ID>

  <Name>Kevin</Name>

</Thingy>

Considering the title of this article, you may be wondering why I've gone to so much trouble to produce POX from my RESTful service instead of JSON. Of course, the answer is that there's a nice story to tell here. To switch from a POX response format to a JSON format, you only need to modify the [WebGet] attribute on your [OperationContract] methods, adding a ResponseFormat parameter.

[ServiceContract(Namespace = "gotnet.biz:JsonPlay")]
public interface IThingySearchService
{
    [OperationContract]
    [WebGet(UriTemplate = "FindThingy?age={age}&name={name}",
        ResponseFormat = WebMessageFormat.Json)]
    Thingy FindThingy(int age, string name);
}

Now, when I invoke my ThingySearchService, I get a JSON-encoded string containing the text '{"Age":44,"ID":1682,"Name":"Kevin"}' which can be cleanly and quickly deserialized into an object on a variety of browsers and platforms. That was a roundabout way of showing you how to build REST/JSON web services with WCF. Hopefully you found the background information helpful. In the next segment, I'll be looking into how you can exercise finer control over the JSON serialization process.

Footnotes:
1
From http://en.wikipedia.org/wiki/REST

 


Categories: Architecture | C# | CapTech
Posted by kevin on Friday, May 08, 2009 7:00 AM
Permalink | Comments (0) | Post RSSRSS comment feed

JavaScript Object Notation (JSON) in .NET Part 2

Welcome to Part 2 of a multi-part series on JavaScript Object Notation (JSON) support in the Microsoft .NET Framework. In this article, we'll focus on the very handy JavaScriptSerializer class. You can find the other parts of this series at these locations:

  • Part 1 - An exploration of the DataContractJsonSerializer class
  • Part 2 - An exploration of the JavaScriptSerializer class
  • Part 3 - JSON serialization from WCF (including a REST primer)
  • Part 4 - Using the JavaScriptConverter class to customize JSON serialization

Welcome back. In Part 1 of this series, we looked at using the DataContractJsonSerializer to dehydrate and rehydrate .NET classes into JavaScript Object Notation, also known as JSON format. In this second article in the series, we'll look at a competing class in the .NET Framework called the JavaScriptSerializer. This class, which is in the System.Web.Script.Serialization namespace and can be found in the System.Web.Extensions.dll assembly, has a somewhat checkered past. It first appeared as part of the AJAX Extensions v1.0 for ASP.NET 2.0. However, by the time the class had made its way into the .NET Framework distribution in version 3.5, it had been marked as obsolete. This meant that while the class was available for use in the current framework of the time, it was likely to disappear altogether in a future release. When we examine the class together below, you'll understand why many developers were upset by the decision to deprecate this class in favor of the WCF-oriented DataContractJsonSerializer.

The DataContractJsonSerializer has one major drawback from the vantage point of many AJAX developers.  Classes that are to be serialized or deserialized must be marked with the [Serializable] attribute or the [DataContract] attribute. In addition, when using the [DataContract] attribute, each member of the class that is to be serialized or deserialized must be marked with the [DataMember] attribute. Whew! That's a lot of markup for something that should be very simple. The JavaScriptSerializer has no such restriction. And what if you want to serialize a compiled class that wasn't marked with the correct attributes at compile time? The DataContractJsonSerializer, being somewhat formal in its approach to satisfying the tenets of Service-Oriented Archicture that Microsoft espouses, makes this scenario pretty much impossible. The JavaScriptSerializer was evidently written by folks on the AJAX Extensions team who felt as my friend Harry Pierson does when he says that it's time to Retire the Tenets. I agree with Harry one hundred percent. Those SOA tenets were developed in a vacuum, in a lab. The real world is messier and dirtier than anything that happens in a lab. Things move fast in the real world and sometimes we just need our specifications to be looser so that we don't get hurt by the impacts that occur naturally in design, development and in production.

These two classes, the JavaScriptSerializer and the DataContractJsonSerializer, put the debate over the tenets into stark relief. Thankfully, Microsoft heard the cry of the AJAXers and un-obsoleted the JavaScriptSerializer in the SP1 release of the .NET Framework 3.5. Thank you, Microsoft! It just goes to show you: if you make enough noise, our friends at Microsoft will respond positively and give us what we need. Of course, we should be polite and professional in our dissent. The pen is truly mightier than the sword. Let's take a look at the JavaScriptSerializer now. For now, this class supports two instance methods of interest:

  • Serialize( object ) : string
  • Deserialize<T>( string ) : T

Given any object, the Serialize method will convert it into a string of JSON text. Conversely, given a type paramter T and a string of JSON text, the Deserialize method will return a new instance of type T. You can think of the Deserialize method like a constructor or an object factory: the raw material of JSON text goes in, an object comes out. Let's start toying with the JavaScriptSerializer by using a provocatively-named class that looks like this:

public class Unserializable
{
    // mix it up - add a field to see
    // it serializes along with the
    // properties defined below
    public int Age;

    public int ID { get; set; }
    public string Name { get; set; }

    // having this default constructor is
    // really important - deserialization
    // using the JavaScriptSerializer
    // depends on its existence to
    // function properly
    public Unserializable() { }

    public Unserializable(
        int age, int id, string name)
    {
        Age = age;
        ID = id;
        Name = name;
    }
}

Notice that the aptly-named Unserializable class has no attributes, base classes or interface implementations that would make it serializable using the half dozen or so patterns that .NET has evolved over the years for such purposes. However, even though the Unserializable class doesn't appear to be serialization-friendly, the JavaScriptSerializer has no problems handling it. Check out the Dehydrate and Rehydrate methods in this code:

private static string Dehydrate(
    Unserializable u )
{
    var jser = new JavaScriptSerializer();
    return jser.Serialize(u);
}

private static Unserializable Rehydrate(
    string jsonText )
{
    var jser = new JavaScriptSerializer();
    return jser.Deserialize<Unserializable>(
        jsonText );
}

private static void Main()
{
    // serialize a POCO that is NOT marked
    // as [Serializable] nor as [DataContract]
    // into JavaScript Object Notation (JSON)
    var u = new Unserializable( 40, 2, "Donna" );
    var jsonText = Dehydrate( u );

    // this will write out the following JSON text
    // {"Age":40,"ID":2,"Name":"Donna"}:
    Console.WriteLine( jsonText );

    // now deserialize (construct) a new object
    // from the JSON text
    var u2 = Rehydrate( jsonText );
    Console.WriteLine( "Age = {0}, ID = {1}, " +
        "Name = {2}", u2.Age, u2.ID, u2.Name );
}

In the Main method, serializing and deserializing the Unserializable class doesn't seem to be a problem. OK, so maybe the Unserializable class wasn't so aptly named after all. It appears that the very handy JavaScriptSerializer class does something that is extraordinary when compared to all of the other .NET Framework object serialization techniques. This little class appears to be able to serialize and deserialize Plain Old CLR Objects (POCO) without a fuss. So simple! And simple is good. I think I like this little class. I'll talk more about this class and the DataContractJsonSerializer in my next article. That's all for now. Enjoy.


Categories: Architecture | C# | CapTech
Posted by kevin on Thursday, May 07, 2009 2:17 PM
Permalink | Comments (3) | Post RSSRSS comment feed