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

Using your iPad for In-Depth Bible Study

March 11, 2011

Happy iPad Day! Right, right... I know some of you are into those Android or Windows tablet holidays, but still, you just can't beat good ol' iPad day! Today the iPad 2 is being released and I wanted to post my latest [epically long] document to help out fellow Christians utilize their iPad more effectively.

About three years ago I published a document called "Using the iPod Touch (and iPhone) for In-Depth Bible Study". Today, I'm releasing the second edition of that called "Using your iPad for In-Depth Bible Study".

I'd strongly recommend all Christian iPad users to look over the document. Seriously, if you are simply relying on the really, really lame Apple commercials or the App Store for your iPad usage, then, seriously... skim the doc!

You may also want to see Jame White's video on his use of technology at http://www.youtube.com/watch?v=VVodV0WB2qg. He and I independently came to the exactly same usages of technology: Android (with it's free tethering, if you get the right model) is epic for phones, iPad is epic for portable 'puting, and the Kindle is epic for reading (and having it read to you!)

The document is at: http://www.netfxharmonics.com/document/ipad/bible

Understanding WCF Faults in Silverlight

July 08, 2009

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

Contents

Introduction

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

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

SOAP Review

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

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

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

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

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

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

Handling Errors

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

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

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

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

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

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

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

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

Applying to WCF

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

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

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

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

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

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

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">This is my error message.</faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope>

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

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

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

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

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

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

Given this, we now have this over the wire:

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

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

Fault Contracts

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

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

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

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

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

So, if you are doing .NET-to-.NET, your client contract DOES have this and WCF on the client will automatically know to use that specific type when deserializing the “detail” part of the fault SOAP message.  Let's see this in action.

First, let's review our previous setup:

//+ basicHttpBinding
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");

This is all that's required to make a .NET-to-.NET WCF call. Setup a address-binding-contract combination to create a channel, then call the operation through the channel. Not a big deal. Now let's add one level of fault handing:

//+ basicHttpBinding
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost.:1003/Person.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
//+
try
{
    Person person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
}
catch (FaultException ex)
{
    //+ without fault contract     
    WriteToOutput("There was an error...(FaultException)");
    //+ this is the message from “faultstring” in the SOAP message     
    WriteToOutput(ex.Message);
}

This example shows handling a fault exception without having the first clue what type is being sent. We can, however, access the fault message by accessing Message property of the fault.  So, in this case, “ex.Message” will contain “Invalid guid.”.  Now let’s go one step further:

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost.:1003/Person.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
//+
try
{
    Person person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
}
catch (FaultException<FaultDetail> ex)
{
    WriteToOutput("There was an error...(FaultException<FaultDetail>");
    //+
    FaultDetail detail = ex.Detail;
    WriteToOutput("ErrorCode: " + detail.ErrorCode.ToString());
    WriteToOutput("Type: " + detail.Type);
    //+ again, this is the message from “faultstring” in the SOAP message
    WriteToOutput(ex.Message);
}
catch (FaultException ex)
{
    WriteToOutput("There was an error...(FaultException)");
    WriteToOutput(ex.Message);
}

In this example, we are taking advantage of the fault contract on the client operation.  Notice that we have access to the  actual detail content that was sent over the wire.  Not only that, but we can access it as a true type via the Detail property of our generic fault exception. This makes things a lot easier.

Remember, the only difference these two examples is the presence of the fault contract on the client operation. If the fault contract were NOT on the client operation, then the "FaultException" catch-block would be caught, not the generic one.

Throwing Exceptions (Bad!)

At this point, you should be able to see that the original fault SOAP message I showed you involving the InvalidOperationException is, in fact, not entirely fictional. It is possible to send an exception over the wire. All you would need to do is something like this (in addition to setting up a fault contract on the client operation):

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

Having said this, throwing an exception over the wire is very poor form. It's not as bad as publicly exposing a private field, using the "var" C# keyword for non-anonymous types, or camelCasing() .NET method names, but it's still viewed as a very poor practice. Why? Well, you tell me. Take a look at the following two examples:

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

... and ... 

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

Notice that the first example (the exception) has many items going over the wire that are never even used, thus wasting serialization and deserialization processing time as well as bandwidth, not to mention making the SOAP message more difficult to read. Notice also that each of the elements in the second example (the fault detail) relate to the task at hand. Therefore, you should always define a fault detail type when dealing with fault exceptions.

Applying to Silverlight

Everything we discussed so far relating to the service applies to Silverlight. That is, you may use the same service for both Silverlight and .NET.  However, if you would like to use the strongly typed fault details in Silverlight as we discussed in .NET, then you need to apply the fault contract attribute to the Silverlight async operation (note: technically this has nothing to do with Silverlight; if you are using async calls in .NET, then Silverlight and .NET will share those).  More specifically, the "Begin" method of your operation contract. Here's an example:

//- BeginGetPersonData -//
[OperationContract(AsyncPattern = true)]
[FaultContract(typeof(FaultDetail))]
IAsyncResult BeginGetPersonData(String personGuid, AsyncCallback callback, Object state);

Note also that since Silverlight is NOT .NET, you have to get the fault detail from the .NET world over to the Silverlight world.  Now, given that nothing about the type is different in the .NET and Silverlight worlds, you can easily share it between the two.  On way to do this is by using the “Add As Link” feature in Visual Studio.  More more ways of sharing types and assemblies between .NET and Silverlight see my document entitled Reusing .NET Assemblies in Silverlight.

Now given this setup, you can upgrade your service access by wrapping your call to the "End" method in a try/catch block.

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)
{
    try { Person person = ((IPersonService)result.AsyncState).EndGetPersonData(result); Write(person.FirstName); }
    catch (FaultException<FaultDetail>)
    {
        Write("There was an error...(FaultException<FaultDetail)");
    }
    catch (FaultException)
    {
        Write("There was an error...(FaultException)");
    }
    catch (Exception)
    {
        Write("There was an error...(Exception)");
    }
};

When you run this, barring any other problems, you can expect that the FaultException<FaultDetail> catch block be called, since that's what's going on the .NET side.  Everything will work the same from here on out.  In fact, if you are doing async calls in the .NET world, your code won’t have any differences at all.

Service Modification for Silverlight

Notice that when I said that the FaultException<FaultDetail> catch block would be called, I said “barring any other problems”.  This is a very important little phrase.  In fact, if you did actually try to run the above example, you would see something rather shocking: the FaultException<FaultDetail> block was NOT hit.  Instead, the Exception block was.  At this point, if you are confused... then you’re probably following along just fine.

Thus, you begin debugging. First, you check the exception message (ex.Message). It says "The remote server returned an error: NotFound.". What? Whatever. Then you realize that you need to see what WCF sent back. So, you open fiddler and rerun the example. You see the following:

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

Well, that's correct. WCF is sending the correct data back. At this point, you go to the next step of debugging by proceeding to bang you head against a wall.

What's the problem?

Here it is: Silverlight a browser plugin. Therefore, Silverlight must obey the rules of plugins and are also limited to the information given to them by their host browser. In the case of fault exceptions, faults are send over an HTTP connect with a non-200 HTTP status code. This makes sense since 200 means “OK” and fault means “not-OK”. Browsers do not send this kind of information to plugins. Thus, not Microsoft’s fault (so, stop cursing them—redirect any and all of that to the IE team). Once we see this truth about the internal mechanics, we can see a glimpse of hope.

How so? Well, the problem clearly has nothing to do with faults. It has to do with the HTTP non-200 status code. Therefore, in order for Silverlight to see the fault exception we need to make sure the service with which the Silverlight client is communicating sends a 200 HTTP status code at all times, regardless of a success or not. This is incredibly easy in WCF using a concept known as an ErrorHandler.

ErrorHandlers are classes which implement the System.ServiceModel.Dispatcher.IErrorHandler interface. One of the required methods that this interface requires for you to implement has the following signature:

void ProvideFault(Exception error, MessageVersion version, ref Message fault)

By implementing this method and registering the ErrorHandler to WCF, you can effectively change the HTTP status code. Below is one implementation of this (notice that name is HttpStatusCode200ErrorHandler not SilverlightErrorHandler-- this can be used for anything that doesn't support non-HTTP 200 codes):

#region Copyright
//+ Themelia Pro 2.0 - Core Module
//+ Copyright © Jampad Technology, Inc. 2007-2009
#endregion
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
//+
namespace Themelia.ServiceModel.Behavior
{
    /// <summary>
    /// Sets the HTTP code to 200 for faults.
    /// </summary>
    public class HttpStatusCode200ErrorHandler : IErrorHandler
    {
        //- @ServiceType -//
        public Type ServiceType { get; set; }

        //+
        //- @Ctor -//
        public HttpStatusCode200ErrorHandler(Type serviceType)
        {
            ServiceType = serviceType;
        }

        //+
        //- @HandleError -//
        public bool HandleError(Exception error)
        {
            return false;
        }

        //- @ProvideFault -//
        public virtual void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            fault.Properties[HttpResponseMessageProperty.Name] = new HttpResponseMessageProperty
            {
                StatusCode = System.Net.HttpStatusCode.OK
            };
        }
    }
}

As you can see, on the created fault there is a Properties bag. By adding our own HttpResponseMessageProperty to this bag under the name of HttpResponseMessageProperty.Name, we can effectively change the HTTP status code.

To install an error handler, just create a service behavior.  A service behavior is much like an operation behavior, but, as you may have guessed, is for a service.  These are really just classes that implement the System.ServiceModel.Description.IServiceBehavior interface.  In our case, all we care about is using the ApplyDispatchBehavior method to install our error handler (this should all sound very familiar since we did something very analogous with an operation behavior and invoker earlier.)  Here’s a sample behavior to install the error handler:

#region Copyright
//+ Themelia Pro 2.0 - Core Module
//+ Copyright © Jampad Technology, Inc. 2007-2009
#endregion
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
//+
namespace Themelia.ServiceModel.Behavior
{
    /// <summary>
    /// Applies HttpStatusCode200ErrorHandler.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class HttpStatusCode200Behavior : Attribute, IServiceBehavior
    {
        //- @AddBindingParameters -//
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            //+ blank
        }

        //- @ApplyDispatchBehavior -//
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(new HttpStatusCode200ErrorHandler(serviceDescription.ServiceType));
            }
        }

        //- @Validate -//
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            //+ blank
        }
    }
}

Now we just need to install the behavior. You can do this in a number of different ways, but I almost always use the service host factory approach.

The purpose behind one of these is to create a service host, which in turn hosts... (drum roll, please)... a service.  As with most WCF features, these are very powerful.  We use them to do all kinds of programmatic service alterations.  For example, we can add custom endpoints, setup metadata, apply more security, or, in our case, install a service behavior (which, in turn, installs our error handler).

A service host factory is simply a class which inherits from System.ServiceModel.Activation.ServiceHostFactory.  To create our service host factory , we are going override the following signature of a newly created service host factory:

ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)

In this method, we are going to create our service host, add our behavior to that host, then return it. Here's the end result:

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
//+
namespace Contact.Service.Activation
{
    public class PersonServiceHostFactory : WebServiceHostFactory
    {
        //- @CreateServiceHost -//
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            ServiceHost host = new ServiceHost(serviceType, baseAddresses);
            //+ HTTP 200
            host.Description.Behaviors.Add(new Themelia.ServiceModel.Behavior.HttpStatusCode200Behavior());
            //+
            return host;
        }
    }
}

Now, we just need our service host to use this factory. Your service host in the context of the web is the /SOMETHING.svc file. All we need to do is open this file and set the service directive "Factory" property to the name of our factory. For example:

<%@ ServiceHost Service="Contact.Service.PersonService" Factory="Contact.Service.Activation.PersonServiceHostFactory" %>

Now we are done.  When your access this service, the service host factory will create the host and add the error handler.  Then, when any error occurs,t he error handler will catch the error and set the HTTP status code to 200.  Thus, the browser will send the fault message to Silverlight and we’ll finally see that the correct FaultException<FaultDetail> catch block is hit.

Conclusion

In sum, WCF provides a very straight-forward, easy to implement fault management solution, which retains the idioms of C# and the purity of the SOAP standard. Not only that, but with a simple flip of a switch Silverlight works flawlessly with the feature that WCF has had since its first release.

Faults are really nothing more than SOAP messages of a certain format.  If there is an error, WCF is smart enough to not just serialize some exception, but, instead, send a fault SOAP message over the wire.  Thus, making the entire error handling process end-to-end very streamlined.

Whereas Silverlight 2 requires some extra massaging in order to get fault contracts implemented, Silverlight 3 has the feature built right in. Using the techniques described in this document, Silverlight 3 developers should be able to keep with the streamlined nature of WCF without the need for any custom fault management.

Samples for this document may be found here.

Accessing WPF Generated Images Via WCF

June 23, 2009

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

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

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

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

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

For completeness, here is the WPF object tree creation:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

100

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Samples for this document may be accessed from here.

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

June 17, 2009

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

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

NetFXHarmonics Code Annotation Format

April 24, 2009

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

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

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

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

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

New Silverlight 3 Features

April 20, 2009

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

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

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

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

Jeff Prosise&rsquo;s Silverlight Tips

April 10, 2009

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

Links

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

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