Wait! Don’t throw out your JSON services!

The Situation

You’ve made an investment in exposing some services for client script consumption.  Most likely if you did it in the past 2 years, that involved exposing your data as JSON formatted objects.

What is JSON?
It is a text-based, human-readable format for representing simple data structures and associative arrays (called objects)

Perhaps a search service returns a list of people formatted using your custom “Person” object and you’ve been using this in your AJAX applications for a while now.  Maybe your JSON data looks something like this:

[{"City":"Queen Creek","FirstName":"Tim","LastName":"Heuer",
"Website":"http:\/\/timheuer.com\/blog\/"},
{"City":"Portland","FirstName":"Scott","LastName":"Hanselman",
"Website":"http:\/\/hanselman.com\/blog\/"},
{"City":"Redmond","FirstName":"Scott","LastName":"Guthrie",
"Website":"http:\/\/weblogs.asp.net\/scottgu"},
{"City":"New Hampshire","FirstName":"Joe","LastName":"Stagner",
"Website":"http:\/\/joestagner.net"},
{"City":"Boston","FirstName":"Jesse","LastName":"Liberty",
"Website":"http:\/\/silverlight.net\/blogs\/jesseliberty"}]

If you squint long enough you can see that this represents what looks like an object that would have this structure:

FirstName, LastName, City, Website

You could consume this in a Javascript function or something in the client script of your web application and nicely iterate through the array of ‘Person’ types, using some human-readable code.

But now you want Silverlight!  And you think to yourself that you need to completely re-write everything to return .NET objects, etc.  Well, not so fast.

JSON Serialization

Because Silverlight 2 supports managed code development, you have some tricks in your bag to leverage existing services that you might not want (or need) to re-write entirely or just right away.  Let’s use the simple example above and assume I now want to use that same service and the same data result in my Silverlight application.  For now let’s assume the endpoint to that service is something like http://foo/mypeople/js.  Most JSON services were a result of using some type of RESTful query model, so essentially your request would likely be a simple GET or POST.

Using Silverlight 2 and the simple WebClient, we can easily get that information from that REST endpoint.

WebClient proxy = new WebClient();
proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted); 
proxy.OpenReadAsync(new Uri("http://foo/mypeople/js"));

Using WebClient, we essentially open a Stream (which is our endpoint) and get the data back.  You can learn more about WebClient and other services with Silverlight by watching my videos about web services and other HTTP-based communication.  Remembering that service calls in Silverlight 2 are asynchronous, we look at our ‘proxy_OpenReadCompleted’ event and could first get our result (with proper error checking of course) which is of type Stream:

Stream strm = e.Result;

Now with that stream (which is essentially the JSON data now), what do we do?  Enter DataContractJsonSerializer.  Remember, we have this available to us thanks to the CLR being in Silverlight 2.  Before we start to use this, however, our client application must be aware of the Type we plan to de-serialize it back into.  So in our Silverlight application we need to have that type defined as such:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
    public string Website { get; set; }
}

Simple enough.  Now we can complete our asynch handler like this and our Stream is now converted into an enumerable type that we can bind, iterate or do whatever we need to with our data.

void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    Stream strm = e.Result;
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person[]));
    Person[] ppl = (Person[])ser.ReadObject(strm);

    if (ppl.Length > 0)
    {
        // do something with the data
        // bind, interate, whatever
    }
}

That’s it!  With a few lines of code we’ve been able to re-use our JSON service and data from Silverlight.  This might not be the best idea in all of your scenarios but it is possible if you want to transition to other services or make re-use out of your investments already.

A Word About WCF Script-enabled Services

For some of you, if you were already a part of the WCF wave when you created your services, you may have already exposed them as scriptable services using an endpoint behavior that was enableWebScript.  This may have been working fine for you but if you look at the output of that, it might be adding some things that you may not need.  This is because it was intended for ASP.NET AJAX consumption (i.e., it adds “_type” and “_d” stuff).  This is easily rectified to make it a cleaner JSON result as well as make the messages smaller.

By implementing the webHttpBehavior in conjunction with the webHttpBinding type for WCF, you will get a much cleaner/smaller JSON payload for your service.  When implementing this, you’ll want to decorate your service methods accordingly using the WebGet attributes:

[OperationContract]
[WebGet(UriTemplate="people", ResponseFormat=WebMessageFormat.Json)]
Person[] GetListOfPeople();

While I’d argue this isn’t completely necessary to use your existing services, it might make your type parsing a little cleaner and as noted, the message size smaller.  So using this (in fact my endpoint this whole time actually is a WCF webHttpBinding endpoint) the entire code looks something like this:

public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(Page_Loaded);
    }

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        WebClient proxy = new WebClient();
        proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted); 
        proxy.OpenReadAsync(new Uri("http://localhost:34907/JsonData_Web/People.svc/people"));
    }

    void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        Stream strm = e.Result;
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person[]));
        Person[] ppl = (Person[])ser.ReadObject(strm);

        if (ppl.Length > 0)
        {
            
        }
    }
}

Easy enough.  If you want to know more about the WCF binding types and implementing full REST services in WCF, check out Rob Bagby’s blog…he has a lot of good material there.

Summary

If you have existing services that you’ve enabled JSON responses for already for use in AJAX applications, consider making re-use of them where appropriate.  This may bridge a transition to other WCF endpoints or other service-types while you are writing your Silverlight applications.

I’ve included my sample project used here so you can tinker and you can download the code here.

Hope this helps!

While Silverlight 2 brings us great capabilities as .NET developers and opens many opportunities for creating rich clients in the browser, it still supports strong media features that have been available since the initial release of Silverlight.  The ability to deliver efficient, high quality media in the browser is an increasing need in a lot of sites producing content for their members.  Traditional ‘podcasts’ which were historically audio-only, are moving increasingly faster to richer media.  This is nothing new of course, but being able to quickly distribute the media on your sites efficiently and provide methods for your users to either embed content, or for you to deliver content to other sites means you need a predictable method for doing that.

In Silverlight 1, while it supported all the same features, one thing that I (and presumably you as well) didn’t find attractive was the deployment scenarios for delivering media content via players.  Silverlight 1 required the distribution of various scripts and initialization functions.  This wasn’t ideal for providing you with something you can just drop into a web page anywhere.  In fact, it was preventative in some places like MySpace, for example.

Silverlight 2 brings a new packaging model, the XAP (pronounced “zap”) file.  Essentially this is an archive file which contains a manifest, reference assemblies and any custom code you have created.  It can also contain resources that your application may use.  Because we have this format now, we aren’t restricted to delivering multiple files for our application…we can deliver our application in one file essentially (your mileage may vary depending on your needs).

Great, now we have a good packaging model, but what about drawing my own controls, etc.?

True, Silverlight 1 had a gap of native controls to the runtime, requiring you to be creative with XAML to deliver functionality.  In the typical media player scenario where you want a few timelines, volume bar, etc…even the trivial tasks required you to wire up some functionality.  Well, Silverlight 2 brings us a common set of controls now that we can leverage.

So let’s take a look at an implementation of a Silverlight 2 media player.  I’m going to use a base player created by Joel Neubeck who has been doing some really great posting on Silverlight lately.  In this example I’m going to try to articulate what Joel did with the base controls and demonstrate how he was able to create an effective use of styling and controls to create a re-usable player.  Additionally, I’m going to add a few new features to it for my desires.

I’m not going to go into the full details of this code, but wanted to point out the key features of what Joel accomplished as I think it was clever use of some controls you might not have considered to use in this scenario.  As well, I’ll show what I added and why.

The Controls

We’ll need a play/pause button, a track timeline, perhaps a download timeline, volume controls, and full-screen button.  We could do these in various ways.  For our buttons we could create canvas elements and add a lot of code to switch them on/off.  We could use a regular button and hide/show different ones.  I thought Joel made an excellent choice in choosing to use a ToggleButton.  The ToggleButton is still a button with all the same features, but supports more than just a normal/pressed state.  Essentially it supports a ‘checked’ state similar to a checkbox or something.  This is useful because we’re using this to basically provide play and pause capabilities.  By using a ToggleButton, we can essentially make the ‘normal’ state the Play view and the pressed (checked) state the Pause view. 

Okay, now for the tracks.  In Silverlight 1 we would have to use a few rectangles on top of each other, add our mouse capture code, etc.  In Silverlight 2, Joel saw the Slider as being an effective way of showing a linear timeline and it provides the functionality for value changing and a thumb for scrubbing, etc.  Perfect.  We’ll use the Slider for the download and volume features as well.

So once we add these to our design surface (Joel chose to create the media controls as a separate UserControl) it looks like this:

Skinning the Controls

Blah.  That looks like crap and rather button-sh.  Here is where skinning comes in.  Jesse just completed a good tutorial on skinning controls that provide a little more depth.  Using this techniques, we can define at a more granular level what we want our content views to be.  For example on the play/pause button, instead of a ‘button’, we replace the content with Path elements that are geometric shapes rather than a typical button look.  In combination now with implementing states in the styles (i.e., Normal State, Pressed State, Checked State) we can define that when the button is pressed (checked) what it shall do/look like by pre-defining the state.

We apply these same concepts to our other controls like the slider, able to skin the timeline area independent from the thumb scrubber, etc.  We put our styles in App.xaml so they are globally available to the application.  Do this with the volume control and other buttons (mute/full-screen) and now our exact same media controls (without affecting any real code that controls the logic), we now have this look:

which looks much more like what we are after. 

Now Joel’s initial example was fixed to a specific size of a media file.  I want my player to scale to whatever the container is.  Essentially I removed all specific sizes from XAML where appropriate and changed the media controls container grid so that the center column (where the timeline sliders are) will expand/contract as needed.  This gives us two features.  The first is that we have a re-usable control area regardless of the media element size.  The second is that when the user goes into full screen mode, the controls also expand to full screen appropriately.  The only thing you have to do is set the containing <div> where this media player is going to live to the desired size (i.e., 640x480) and the application will scale the internal elements to fill that space accordingly.  Full screen mode will as well adjust the controls to fill the screen.

I also added a bigger “Play” indicator (and buffering indicator) that would show in the center of the MediaElement when paused or buffering.  I felt this gave more visual cueing to what was going on with the media.  This also scales as it looks at the ActualWidth/Height properties and grabs the center points based on that.  Here’s the resulting paused view in two different sizes:

640x480 view

320x240 view

Providing Startup Parameters

The next thing I wanted to do is eliminate the hard-coding of the MediaElement Source property in the base XAML file.  I just created a player with all my needs and want to re-use it without recompiling, etc.  Here’s where InitParams comes in for developers.  One thing we can do to the plugin is pass startup parameters to it.  These are surfaced using the InitParams functionality.  You can specify a comma-delimited list of name/value pairs in this property like:

firstName=Tim,lastName=Heuer,loves=Silverlight

which in turn get put into a Dictionary object in code.  These elements are retrievable in your applications Application_Startup in the StartupEventArgs.  the Application_Startup is in the App.xaml file (you can think of this as a global.asax file if you are an ASP.NET developer).  There are different ways you can implement grabbing these values out.  You could pull values (or just one value) out using a simple retrieval of the key value:

string firstName = e.InitParams[“firstName”].ToString();

You could set this to a public static variable that could then be accessed by your application.  I chose to simply iterate through the initialization parameters and add them to the resources collection of the application.  I haven’t decided yet if this is the most effective use, but for now it works and was simple:

foreach (var item in e.InitParams)
{
    if (item.Key.ToLower() == "m")
    {
        string mediaParam = e.InitParams["m"].ToString();
        Uri mediaUri;

        if (mediaParam.Contains("://"))
        {
            mediaUri = new Uri(mediaParam, UriKind.RelativeOrAbsolute);
        }
        else
        {
            mediaUri = new Uri(mediaParam, UriKind.Relative);
        }

        this.Resources.Add("m", mediaUri);
    }
    else
    {
        this.Resources.Add(item.Key, item.Value);
    }
}

You’ll see that i check for an “m” parameter and do an additional checking on that.  I’m using this parameter for passing in the source for the MediaElement and need to check if it is an absolute URI or if the media will be local to the Silverlight application.  Then any other initialization params get added to the collection as well.  This might not make sense because I’m really only using two: source and autostart and if I wanted to make this re-usable, I would really need to build up more options and put them in the code too, or else nothing is being used.  I’ll likely do that later, so let’s move on.

Now that we have these items in our Resources collection, my app continues to load and set the MediaElement source to that value:

mediaPlayer.Source = App.Current.Resources["m"] as Uri;

As a // TODO I need to add some error checking and display the thumbnail if there is a problem perhaps, but I’ll get to that later.  Anything else I might need to do with the startup params I can get them out using the same method as above now that they are in my Resources collection.

So now in my control hosted page I have this:

<div style="width:640px;height:480px">
    <asp:Silverlight ID="Xaml1" runat="server" 
    InitParameters="m=LEADER_ST2.wmv,autostart=false" 
    Source="~/ClientBin/VideoPlayer.xap" Version="2.0" 
    Width="100%" Height="100%" />
</div>

Here I was using the asp:silverlight control which exposes the InitParameters property, but I could use the object tag directly:

<object data="data:application/x-silverlight," type="application/x-silverlight-2-b1" 
        width="640" height="480">
    <param name="source" value="ClientBin/VideoPlayer.xap"/>
    <param name="onerror" value="onSilverlightError" />
    <param name="background" value="white" />
    <param name="initParams" value="m=LEADER_ST2.wmv" />
</object>

NOTE: In the “m” parameter it will use the standard path resolution that Silverlight respects.  For more information on this, see a great post by Pete Brown on the explanation.

Providing Alternate Content

As you can see we have provided no alternate content for the object tag implementation.  The asp:silverlight control also supports providing alternate content via the PluginNotInstalledTemplate property.  This is the responsibility of the web developer implementing any active content, whether it be Silverlight, Flash or other embeddable technology.  For more information on methods of doing this, read my blog post regarding a great deployment experience.

Summary

Now I have a media player that expands to the size it needs as well as is totally re-usable for me as I can provide startup parameters to it providing the media to play.  There is some polish that probably needs to occur, but as you can see, by using the native controls we get a lot of free functionality that we can tap into and by skinning the controls you get a much better look than the default and can even totally change the visual behavior of native controls.  Thanks to Joel for his great work using native controls and state parts and skins to create a great media player.  I’ve only made a few tweaks that I think were value add, but download the code and see what you can make with it. – all you need to do is change the styles and let’s see what you come up with!

Here’s the source as it is right now with my modifications to Joel’s existing work: VideoPlayer.zip.

UPDATE: Updated code using VisualStateManager and beta 2 styling method is here.

My new team does a lot of video conferencing (I think ScottHa has a picture of our last meeting somewhere on the internets).  I’m still getting used to it a bit, and network latency gives me the willies when there is such a delay in audio or choppiness.  Nonetheless I like being able to “see” people, so I haven’t written it off just yet.

My last 1:1 meeting with my boss also reminded me of geek sounds.  After talking about something he was going to fire off a message to another colleague to connect some dots.  So he paused and started typing.  I swear he uses this keyboard:

I recorded a quick snippet for my own archives…I love the sound of a solid keyboard:

It was too funny not to pass up, sorry Simon.

While you may not personally work with a lot of media solutions in your Silverlight application, it is nice to know the quality is there when you need it.  Silverlight supports the VC-1 codec for media which provides a standards implementation for high quality media.  I would imagine that most developers probably don’t know/care what all that means.  But if you are deploying a high-touch media solution (i.e., online TV, etc.) you want that high quality.

Our resident media expert, Ben Waggoner, just put up a great (and detailed) post about some ‘high-touch encoding’ techniques he uses and does some comparisons to some media outputs with FLV files as well.  There are some gory details for tweaks in the media outputs, much of which I won’t pretend to understand as an expert, but as a geek they seem to make sense :-).

One of the most compelling comparisons Ben notes is the quality from the VP6 (what FLV uses) and the VC-1 codec in a particular image…notice the shirt texture difference.  The VC-1 output in this sample is much more close to the original source.

FLV:

VC-1:

Ben admits in some areas he’s not sure why there is such a difference (i.e., the FLV is darker it appears as well).  It is an interesting article to read and he provides all the details, sample files and implementation for you to examine.  A lot of the things he shows for the tweak settings are a part of Encoder 2 which is to release soon.

For Silverlight 2, we finally have some native controls to leverage.  Most of them are to aid in input scenarios.  The text input, however, is currently scoped to be plain text input.  Some have desired a richer input control.  You knew it wouldn’t be long before someone in the community stepped up to the challenge.  Christopher Husse has done just that.

Enter: Silverlight rich text editor.

He posts a detailed description of all the capabilities on Michael Syncs blog.  The effort is also posted on Codeplex for you to peruse.

Here is what he calls the ‘incomplete feature list’:

    • Copy/Paste formatted text between RichTextBoxes and copy/paste from/to clipboard of unformatted but macro-enabled text. This means in windows clipboard even things like emoticons will be kept.
    • You may insert line breaks, unordered lists and blockquotes.
    • You may use various keyboard selection features like End/ Home/ PageUp/ PageDown/ Left/ Up/ Right/ Down, Ctrl+A/ End/ Home, Ctrl+Shift+End/ Home/ Left/ Right, Shift+End/ Home/ PageUp/ PageDown/ Left/ Up/ Right/ Down and so forth…
    • Supports direct Unicode character input using “Ctrl”+[NumPad].
    • All silverlight font formatting is supported and even some more like SUP/SUB formatting.
    • You may define macros and a proper object class that should replace matching text, like emoticons…
    • In contrast to many other rich text editors, this one is fully real-time. That means no preview is required because the editor allows editing all things directly.
    • If you only use macros and IRichTextObject to extend the control, you will automatically get support for secure content serialization of all control elements. Content serialization also supports to reload content and edit it again.
    • Secure content serialization gets rid of any potential security leak when storing user typed formatted text on a server and presenting it to visitors, because it is fully verifiable.
    • You may restrict font formatting to a well defined custom subset. This allows you to ensure that all user typed input matches your needs or website design. (this feature is currently not implemented, but only prototyped)
    • Snapshots allow convenient access to formatted content and also Find&Replace with regular expressions for example…

Way to go Christopher!