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

Understanding WCF Services in Silverlight 2

Sunday, November 16, 2008

Contents

Introduction

In my article entitled Creating Streamlined, Simplified, yet Scalable WCF Connectivity, I explained streamlining and simplifying WCF connectivity and how you can use a private/public project model with WCF channel or a ChannelBase access to simplify your WCF connectivity.  In this discussion, I would like to move our attention to the world of Silverlight.  However, before we begin, it would probably be beneficial to you to review the concepts I wrote about in that article.  Knowledge of the service and data contracts in the sample project is important for this discussion.

To begin, let me start off by reminding everyone that you shouldn't really rely on "Add Service Reference" in Visual Studio for magical service client creation.  Frankly, the code is incredibly verbose, hard to manageable, edits are prone to being overwritten, and is almost always used as an excuse to not learning WCF.  This is true for .NET and so very much more true in Silverlight.  There's a reason Juval Lowy, in all his books and talks, repeatedly tells people to avoid using it.  Fortunately, as professionals, we have the ability to understand how to do things without magic.

Since we are talking about WCF, we are talking about a system with a single consistent model.  The concept of the ABC in WCF works the same for Hello World as it does for the most complex sales processing system.  You need an address, a binding, and a contract for all WCF communication... or, well, any communication anywhere, even when talking to another person.  You have to know to whom, how, and what.  If you don't have these three, then there can't be any communication.  With these three pieces of information, whoever, you can create a WCF channel to use for all service communication from ASMX interop to TCP connectivity to Named Pipes.  WCF is completely streamlined.

However, since we are in the world of the web, there's one difference in how we access the services from our clients: we are dealing with asynchronous calls.

The Async Pattern

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

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

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

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

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

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

Before we see seek to understand WCF in Silverlight using the Async Pattern, though, let's review how to access a WCF service using .NET so we can have a basis of comparison.  As previously mentioned, all you need for any communication anywhere is an address (to whom), a binding (how), and a contract (what).  This isn't just fancy marketing talk or something from a watered down presentation at a local free conference, the ABC of WCF is real.  This is all you need.

As explained in my Creating Streamlined, Simplified, yet Scalable WCF Connectivity article, when you create a WCF service contract in .NET, you can reuse this same contract on both the service-side and the client-side per a private/public or service/implementation/client model.  Below is the service contract used on the service-side for the duration for this article.  This also services as the template for our Silverlight version of the contract.

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

We can use this contract with a binding and an address to create a channel, which you then use to communicate to the service.  Here's all that's you need to do do call the WCF service:

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

Replace BasicHttpBinding with NetTcpBinding and you have TCP communication, replace it with NetNamedPipeBinding and you have named pipes communication.  It's that simple.  No magic, code generation, parsing, fancy client tools, or even configuration is required.  Just create a channel and make the call.

This is essentially the same type of thing that you would do in the world of Silverlight, but we need to do this following the Async Pattern.  This means that our service contract in Silverlight will actually look slightly different than our service contract on the service.  Here's our Silverlight version:

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

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

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

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

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

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

Notice also also that the callback has a call to Dispatcher.BeginInvoke.  You must do this if you are on a visual element and want to access visual elements in your callback.  This will grant you access to the UI thread.  Without this, an exception will be thrown.

External Web Site Access

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

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

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

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

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

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

Now our WCF Silverlight service will work flawlessly.

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

Configuration Based Access

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

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

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

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

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

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

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

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

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

Strongly Typed Client

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

If you need to add more operations, and you most definitely will, all you need to do is copy/paste this pattern and do a which rename of a new things here and there.  This will give you complete control over all your entire WCF in Silverlight.  Using this class is now as simple as the following:

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

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

//- $OnServiceCallback -//
private void OnServiceCallback(Object sender, ClientEventArgs ea)
{
    Person person = ea.Object as Person;
    if (person == null)
    {
        return;
    }
    this.Dispatcher.BeginInvoke(delegate
    {
        spMain.Children.Add(new TextBlock
        {
            Text = person.FirstName
        });
        wait.Set();
    });
}

As simple as this is, though, you could actually keep the simplicity of this usage and still upgrade the class to be a bit more general.  For this reason, I created my ObjectClient<TServiceContract> class, which is now part of my Themelia for Silverlight product (to be released in the future; see my .NET Themelia Framework here).  Here's an example of using it:

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

Then, here's the service callback:

//- $OnObjectServiceCallback -//
private void OnObjectServiceCallback(Object sender, ObjectClient<IPersonService>.ClientEventArgs ea)
{
    Person person = ea.LoadResult<Person>();
    this.Dispatcher.BeginInvoke(delegate
    {
        spMain.Children.Add(new TextBlock
        {
            Text = person.LastName
        });
        wait.Set();
    });
}

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

Below is the ObjectClient code in its entirety:

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

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

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

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

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

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

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

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

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

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

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

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

JSON Client Access

If you've been paying attention to the examples thus far, we have only been using the BasicHttpBinding binding.  This is because it's the only native on that is supported by Silverlight 2.0.  However, since we're on the web, we may very well be creating a Silverlight client to replace an AJAX client which used a WCF JSON service.  Or, perhaps, you just prefer to use a JSON endpoint on your WCF service.  Therefore, we need to be able to access JSON services efficiently.  To do this, we turn to the System.Net namespace, namely the WebRequest class.

Essentially what we want to do is create an instance of the System.Net.WebRequest class and setup an async call chain.  But first, you need to know the full URI you are going to access.  This URI is the base endpoint address of the service combined with the relative endpoint address combined with the name of the service operation you are going to access.

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

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

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

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

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

At this point we have the raw data sent back to us from the service.  One hitch here is that an unmodified WCF JSON service likes to send back JSON with full namespaces for each member.  Here's an example of what I mean:

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

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

When we get our response data back in our final WebRequest callback, we can use the static System.Json.JsonObject.Load method to load a stream or TextReader into a System.Web.JsonValue object.  This will give us a representation we can use to access any information we want by accessing the indexer of the object.  However, before we can access our data, we need to open the data envelope.  This is that "d" section in the WCF JSON response message.  This is as simple as accessing the "d" indexer on the JsonValue object.  Here's what were talking about so far:

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

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

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

At this point, if you're working with a JsonObject, as we will be in our example, you may access any member of the JSON data you want.  You do this by reading values from a JsonValue by writing them to a stream or text writer.  For example, here's the code to access the FirstName value:

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

As you might imagine, I created my Themelia for Silverlight framework to abstract most of this stuff away from everyone and to simplify JSON and XML service access.  For now, however, here's a simple and to-the-point WCF JSON client:

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

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

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

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

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

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

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

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

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

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

            }
        }
    }
}

Here's a sample of using it:

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

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

//- $OnJsonServiceCallback -//
private void OnJsonServiceCallback(Object sender, WcfJsonClient.JsonValueEventArgs ea)
{
    this.Dispatcher.BeginInvoke(delegate
    {
        StringBuilder builder = new StringBuilder();
        StringWriter writer = new StringWriter(builder);
        ea.JsonValue["FirstName"].Save(writer);
        //+
        String firstName = builder.ToString().Replace("\"", "");
        spMain.Children.Add(new TextBlock
        {
            Text = firstName
        });
    });
}

Thread Waiting

Many times when working in the Async Pattern, you will have an async chain with one service call's callback call another service, which in turn has a callback which calls another service.  This is an effective way to manage the order or events in an application.  However, depending on what you're doing, this model may not be the entirely optimal.  Fortunately, we have another option: a thread wait.

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

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

private AutoResetEvent wait = new AutoResetEvent(false);

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

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

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

Using DevServer

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

My NetFXHarmonics DevServer is a development web server which provides multi-instance web server hosting and the ability to look at the traffic in and out of each web server.  Using this, you can host all your development servers in one centralized location, allowing you to attach your debugger to DevServer.Client.exe instead of many different WebDev.WebServer.exe instances.

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

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

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

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

DevServer

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

Conclusion

As you can see, there's more to Silverlight connectivity in WCF than the naive "Add Service Reference" option.  By simply understanding the mechanics of what's going on, we are able to tailor a solution to our specific needs.  WCF requires nothing more than an address, a binding, and a contract and with this information we can create a channel to access our service without the need of any extra overhead.  Or, in the case of JSON, we can use tools already provided to us to obtain the exact JSON fields we need.  You clearly have many, many options for Silverlight networking once you understanding the mechanics of Silverlight and WCF.

Links

Love Sudoku?  Love competition?  Try the new Sudokian.com experience today.

(0 Comments)

March 2008 Web Technology Update

Wednesday, March 5, 2008

Recently a bunch of technologies have been released and/or updated and I would like to mention a few of them briefly.

First and foremost, Silverlight 2 Beta 1 has finally been released and you may download it immediately.  There is also an accompanying SDK.  You can find a nice development tutorial series on Scott Guthrie's blog.  If you are already familiar with WPF, you can just skim this entire series in less than 5 minutes.  Given that this technology isn't the same as the full WPF and given that it's designed for the web, there will obviously be differences.  It's important to remember that Silverlight 2 isn't simply WPF for the web.  I would call WPF 3.5's XBAP support for IE/Firefox "WPF for the web".  No, this is possibly the biggest web technology improvement since the release of Firefox 1.0, which in turn was the biggest technology release since the printing press.  Alight, alight... since .NET 1.1.  It's support for the dynamic language runtime is going to completely revolutionize our web development.

When reading through Scott's tutorial series (serious, at least skim it), it's interesting to note that Silverlight 2 allows cross-domain communication.  It does this by reusing the Flash communication policy files.  This is really awesome as it means that you can start accessing resources that Flash has been using for a while.  Being able to dynamically access resources from different domains is critical to the success of web architecture in the future.

Speaking of cross-domain communication, John Resig and I received a very depressing e-mail the other day telling us horrible news: cross-domain communication will probably be removed from Firefox 3 before it's official release.  Apparently a bunch of paranoid anti-architects were complaining about the dreaded evils of being able to access resources from different domains.  Um ok.  Fortunately, however, Firefox 3 has a feature called postMessage that allows you to get around this.  Malte Ubl has produced a library called xssinterface to demonstrate just this concept.  You could, of course, get around this completely with some iframe hacks or some other scripting magic.

Speaking of web browsers, I would like to bring people's attention to a technology that I've been following for some time now: Apple WebKit.  This is basically the brains inside Safari.  I absolutely love the Safari web browser.  It's by far and away the easiest web browser to use.  It also has the same keyboard short-cuts as Firefox, which is how I'm able to use it.  It's also incredibly fast, but I should mention that it uses even more memory than Firefox.  My last instance passed 500MB.  Given it's lack of an extension or configuration (i.e. about:config) system, it's obviously no where near the same caliber as Firefox though.  It is, however, my primary web browser as has been since October '07.

The reason I mention WebKit is because as very few people know, this is an open source project and has nightly binaries released on their webkit.org web site.  One of the most interesting thing about nightlies that you can actually watch the progress of development as time goes on.  About every month or so I like to get the latest Firefox nightly.  It's always interesting to see the major experiments that the developers try about 2 months after a major release of Firefox.  There's always some really awesome "teaser" feature in there that later grows into a fully grown technology.  The same can be said for WebKit.

None of that is, however, my primary reason for mentioning WebKit.  As, most web developers know, the Acid2 test has been the standard for checking a web browsers compatibility with the CSS standard.  I've been pushing this test for a long time, but I've never pushed it as the only test.  There are many things that a web browser must do and many features a web browser must have before it can be considered appropriate for use.  Merely focusing on CSS, while completely ignoring DOM support, JavaScript, and general user usability can lead a browser to be as impossible to use as Opera 9.

As I've said time and time again, I'm not a CSS specialist.  Part of the definition of being a professional web develop is that I have a solid understand of the inner workings of CSS including specificity, the various selectors, and how to merge absolute, floating, and relative position on the same elements, tasks "coders" see as nearly impossible to learn.  However, my focus is on AJAX interaction as seen from the JavaScript and DOM worlds.  Therefore, we need to have a test for browsers that goes beyond the simple Acid 2 test for CSS.  I'm not the only one thinking this way, because recently the Acid3 test was published and it tests CSS, JavaScript and DOM support.  This is the new standard for web browsers.

So far no web browser has even gotten close, with the lowest score from a web browser being 39% in Safari to the best score being 50% in Firefox 2.0.0.12.  However, in terms of non-released software, Firefox 3.0b3 has a score between 59% and 61%, depending on its mood (update: b4 is steady at 67%) and the latest WebKit nighty has a score is 90% (watch WebKit progress on Acid 3 at http://bugs.webkit.org/show_bug.cgi?id=17064).  That's phenomenal!  The newly released Internet Explorer 8 beta 1 has a score of 17%.  Those of you who have naively praising the IE team for being YEARS late on getting near the Acid 2 test need to wake up and realize this is 2008.  Time moves-- keep up.  Firefox has been close for the longest time and has always had the next-gen's next-gen JavaScript and DOM support, but has only recently completely passed the finish line of the Acid 2 test.  So, they are finally off my watch list there, but I will not stop bugging them until they pass the Acid 3 test.

For more information on the Acid 3 test, see John Resig's most entitled "Acid 3 tackes EMCAScript".  He's about as passionate as I am for web standards and Firefox and his blog is an invaluable resource for all things JavaScript.  His work is so good that I would like to take the time to plug his book he is currently writing: Secrets of the JavaScript Ninja.  I absolutely guarantee you that this book will redefine the entire world of JavaScript and will raise the bar incredibly out of the reach of "coders". To all of you coders who think you know JavaScript, do a view-source on the Acid 3 source code (you may want to bring a change of underwear with you).

Lastly, it's not necessarily a "new" technology, but it's so incredibly phenomenal that I need to mention it: Prototype 1.6.  It's amazing to me that people actually go out of their way to use ASP.NET AJAX 3.5 (I still find the ICallbackEventHandler interface more productive).  ASP.NET AJAX 3.5 is not nearly as bad as extremists think, but the design is still flawed.  Prototype on the other hand is absolutely incredible.  I've written about Prototype before, but this version 1.6 is even more powerful.  There a A LOT of changes from Prototype 1.5.  It's so good that I no longer call it "prototype/script.aculo.us".  Script.aculo.us is a great animation system, but, honestly, the main reason I used it was for the DOM abstraction in the Builder object.  Prototype now has an Element object to help create DOM objects, thus allowing me to remove Script.aculo.us from most of my projects (it's not as complete as the Builder object, but it allows object chaining-- which greatly increases code readability, conciseness and understanding!).  The Template object is also amazing as it gives you the ability to go far beyond simple String.Format formatting.  The new Class object for OOP is also great.  It's so much easier to use than Prototype 1.5.  Also, being able to hide all elements with a particular CSS pattern with one shot is very useful! (for example, $$('div span .cell-block').invoke('hide')).  It even allows you to use CSS 3 selectors on the most dead of web browsers.  It really makes developing for Internet Explorer 6 and 7 bearable!  Even if I have to use ASP.NET AJAX 3.5, I'll still including prototype.js.  If you do anything with JavaScript, you need Prototype!

 

Links

(0 Comments)

Silverlight 1.0 Released

Wednesday, September 5, 2007

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

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

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

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

Related Links

(0 Comments)

Silverlight 1.0 Release Candidate Finally Out

Friday, July 27, 2007

For those of you who don't know, Silverlight 1.0 Release Candidate has been released.  If you haven't tried Silverlight out yet, this would be a good time to do so.  Be warned though: you need to know the fundamentals of Modern JavaScript to work with it.

In an effort to help educate the community on these topics, if you re not familiar with Modern JavaScript (i.e. multicast events, closures, anonymous functions, Ajax, prototype orientation, namespaces, etc...) please send me an e-mail and I will advise you.  Having said that... in almost every case I'll probably tell you to go buy Pro JavaScript Techniques by John Resig.  Oh any btw... being able to do validation or form processing in no way means you know JavaScript :)

(0 Comments)

Extremely Misunderstood Software

Friday, July 27, 2007

Today I was thinking about some of the misunderstandings going around about software. Actually my life revolves around misunderstandings in every area of my life (not just my life in technology!) and I'm usually thinking about it in some respect. I can recall back to early 2004 when I was the black sheep in both the Microsoft AND Mozilla communities for promoting .NET *and* web standards. The Mozilla-ish (open-source) guys would mock the severe inefficiencies and painful security flaws of .NET (though they never ACTUALLY used .NET!) and the Microsoft-ish (.NET) guys would mock call me personally unrepeatable names for even suggesting that web developers should learn the foundational principles of JavaScript, CSS, and XHTML before they starting asking a load of "how do I..." questions. Now while the open-source community has wised up a bit, I still get extremely vile insults from the git-r-done areas .NET community where even mentioning proper development or training will get you killed. In any case, this is my life and like I say... not just in technology. Basically, everyone hates me :)

So, here's my concise (yeah like I'm capable of that) list of software that is EXTREMELY misunderstood. I'm not going to go into any detail except put a single line by the item which should give you a hint as to what the software really is. This is important: if you understand one of the confusions, that confusion is analogous to each of the others. For example, if you know how insane it is to compare SQL Server 2005 to MySQL then, guess what... you now understand why it's insane to compare Firefox to IE or LLBLGen Pro to .netTiers or NHibernate. You just can't do it! Yet, people all day long give me unjustifiable grief about this stuff and I am forced to spend literally 70% of my time in marketing instead of programming!

I'll shut up now... here's the list:

List of Extremely Misunderstood Software

(0 Comments)

Moonlight: Mono's Silverlight

Monday, June 25, 2007

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

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

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

(0 Comments)

Silverlight's Adoption as Public De-Facto Standard

Wednesday, June 20, 2007

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

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

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

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

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

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

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

(0 Comments)

Reflecting Graph Video Demo

Sunday, May 13, 2007

For those of your who have not installed Silverlight, below is a link to a video of the demo. As you will see it works perfectly in Firefox and IE.

Links