Demystifying The Code

Moving to London – The Housing Trip

As some of you might know, my wife was recently offered a great position in London with her company.  At the suggestion of a friend of mine, I have decided to chronicle the experience on this blog.

 

The Process

Moving unto itself is a huge process.  Moving overseas adds a whole laundry list of additional complexities.  To start with, there is the procurement of the Visas.  Secondly, the moving of your stuff is split up into an air shipment which takes 4 weeks or so and a sea shipment which takes a couple of months.  Thirdly, it is pretty costly to travel overseas, so you are generally limited to a single trip prior to moving to find your housing.  Lastly, due to the length of time it takes to ship your furniture, sheets, pots, pans, etc., you can expect to stay in temporary housing for a decent period of time – a month or so.

Now, my wife’s company understands all of this, so they hire a relocation company to help us with all of these details.  This is where our story begins.

 

The Visas 

Attaining our Visas was our first challenge.  In order to help guide us through these unknown waters, our relocation company assigned us a representative knowledgeable of the process.  From the very beginning we told our rep that we had a housing trip planned the third week in November.  The trip was 3+ weeks prior to our move.  We wanted that kind of buffer because we were not sure what size house / flat we would find.  As a result, we did not know whether our furniture would fit or not.  Given a smaller place, we would have to put some furniture in storage, as well as purchase some more appropriately sized furnishings.  Our representative assured us that we would have our Visas in time.

Having a big company sponsor you is a huge help in gaining a Visa.  There are, however, still some obstacles.  For instance, the UK wants to ensure that you are able to pay for housing for at least your first month there.  The means by which they validate this is to ask you to illustrate that you have maintained a minimum balance of something like $3000 in a checking or savings account over the past 6 months. 

I’m not sure how you roll, but we do not maintain a savings account.  Our “extra” money goes into the market in an investment account.  As for our checking account, we do maintain an average balance of over $3000.  However, we do not maintain a minimum balance of $3K.  It has fallen well below this floor.  Truth be told, It has actually fallen below 0.  Although we assured our representative of these unfortunate truths, she insisted that we burn thousands of calories gathering this documentation for her.  We were able to put together the requested documentation after 10 days or so (we had to request official copies from the bank because we get our statements online) and forwarded them on to her.  She crunched all of our information against her years of experience and her professional opinion was – wait for it – we had not maintained a balance of at least $3000.  She is good!

I hope I didn’t misrepresent the situation.  Reading the above you might have come to some wrong conclusions.  Specifically, you might have assumed that, upon receiving the documents, coupled with our verbal assurance, it was instantly clear to our seasoned representative that we did not meet the criteria.  That was not the case, as we heard nothing for days.  We began pinging our rep, wondering what our recourse was, only to get out-of-office replies.  Apparently, our financial position caused enough stress to require a brief vacation.

Upon her return, we found out that our only recourse was to request a document from my wife’s company guaranteeing payment of our housing for the first month.  We thought that this was a no-brainer.  As part of my wife’s package, her company was putting us up in temporary housing for – you guessed it – a month.  Silly, silly me.  Gaining this seemingly simple guarantee took close to a month (I can’t remember exactly, but I think there may have been a small vacation in there too).

The net-net was that, despite constant assurance that we would have our Visas in time for our housing trip, they were a few days late.  As a result, we had to push back our move date a few days and reschedule our housing trip to a few days before our move.  I’ll get into that more in coming posts…

Uncle Fergal Helps Us Pronounce Azure

On the advent of PDC 09, I wanted to pass along one of my key learnings since PDC 08.  As you probably know, it was at PDC 08 where Microsoft introduced our cloud platform Azure.  From that day on, there has been mass confusion as to the pronunciation of Azure and the issue quickly reached pandemic proportions.  I’ve personally witnessed everything from az-yoor to ah-zher to as-sure.  I would have been willing to simply ignore the verbal missteps had it not been for a sign…  literally a sign…

churchsign1

I racked my brains for days following my encounter with that sign.  Who or what is a Fergal?  It was perplexing.  The only thing I could think of was that I have an Uncle Fergal in Scotland.  Maybe the sign wanted me to contact my Uncle Fergal, ask him how to pronounce Azure and to spread the word.  Well, as they say, when in Scotland …  The following is part of my conversation with Uncle Fergal.

Install Microsoft Silverlight

FergalLarge(Uncle Fergal)

Patterns-Based Silverlight Development – Part IV – Service Layer

In this post, I will be building the WCF Services layer that my client layer will call.  I will be using the custom binding made available with Silverlight 3 that enables a decreased message size through encoding the message as binary rather than text.  I will also write some code to test this layer.

 

Adding the WCF Service

Add the web

Before I can add the WCF service that my Silverlight component will consume, I need to add the Web application to my solution.

  1. Right-Click the Server solution folder –> Add –> New Project
  2. Under Visual C# –> Choose ‘Web’ –> ASP.NET Web Application
  3. Name it HelpDesk.Web
  4. Delete Default.aspx

Add the service

In Silverlight 3, we re-implemented the ‘Silverlight-enabled WCF Service’ template.  In Silverlight 2, the template wired up the basicHttpBinding.  If you know your WCF, you know that this is the ‘Interoperable Binding’, conforming to the WS-I Basic Profile 1.1.  In Silverlight 3, it wires up a custom binding

  1. Right-Click HelpDesk.Web –> Choose ‘Add’ –> New Item
  2. Under Visual C# –> Choose ‘Silverlight’ –> ‘Silverlight-enabled WCF Service’
  3. Name it TicketService.svc
    image
  4. Add a project reference to HelpDesk.Data.  We will need that.

Out-of-the-box Configuration

Let’s take a look and see what  the ‘Silverlight-enabled WCF Service’ template gives us out-of-the-box.  See below:

image

You will notice that the bindingConfiguration points to a customBinding.  This binding configures a binary message encoder that encodes Silverlight messages in binary on the wire.  This binary format is compatible with the Windows Communication Foundation (WCF) binary message encoder.  This will result in decreased message sizes.  The caveat is that you should revert back to basicHttpBinding if you have non-.NET clients, as this binary format is WCF-specific.

As I stated, this is the out-of-the box configuration.  We will need to make some additions in order to allow us to propagate our exceptions to the client.  We’ll take a look at that now.

 

Handling errors with FaultException<T>

I tend to think of exceptions falling into a couple of categories:  1) Business exceptions – exceptions that the user caused and can resolve.  Breaking validation rules falls under this category.  2) Technical Exceptions – exceptions that the user did not cause.  An example would be that the database is down.  3) Security Exceptions.  In our application, we need a way to pass all kinds of exceptions to our Silverlight client.  Further, in the event of a validation exception, we need to let the client know which rules were broken.

This was a bit of a challenge prior to Silverlight 3.  Now, with some work, we can pass exceptions from our services layer to our Silverlight client with FaultException<T>.  Why did I write “with some work”?  Well, it is important to understand that Silverlight 3 defaults to using the browsers networking stack for HTTP calls (you can opt in to using another networking layer called the client networking stack).  By default, a FaultException will be sent to the client with a 500 HTTP status code.  What this means to you is that Silverlight will not be able to access the bodies of these messages.  What the client will see is a 404 NOT FOUND.

In order to make this work, we need to configure the WCF service to set the status code to 200 (OK).  Don’t worry, it will still be seen as an exception on the client.  We will see that in a moment.  First, let’s get it set up.

Creating our Silverlight.Patterns Project

Until now, I have been adding some generally re-usable classes to my HelpDesk.Data project and that is just wrong.  I am going to add a project that will contain classes that I will be able to re-use over and over again… classes like the RuleViolation or my ValidationException.  (I should note that I did have to decorate my RuleViolation class in order to make it serializable).  I will also add another class or two here.  First, I am going to add the project, move these 2 classes over, change their namespaces and set the appropriate references.  I am not going to detail all of that work in this post, as it is grunt work.  Please feel free to download the code from this session and you will see the changes reflected there.  One last thing, before I move on…  I stink at naming assemblies, so if you have any suggestions for a better name than Silverlight.Patterns, please lay a comment on my blog.  I am all ears.  For now, I will be adding these classes to that project and will use Silverlight.Patterns as the root namespace.

Adding a the SilverlightFaultBehavior class

As outlined in the online documentation article Creating and Handling Faults in Silverlight, we are going to create a WCF endpoint behavior that will set the HTTP status code to 200 for Silverlight FaultExceptions.  I will create this behavior in my new Silverlight.Patterns project.  Now, I am copying the code directly from the link above, so I am not going to show it all in this post.  You are free to download the code for this article and see it, though.  I will show the important pieces here. 

namespace Silverlight.Patterns.Faults
{
    public class SilverlightFaultBehavior : BehaviorExtensionElement,
        IEndpointBehavior
    {

        public override Type BehaviorType
        {
            get { return typeof(SilverlightFaultBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new SilverlightFaultBehavior();
        }
        ...

You can see above that we created a class called SilverlightFaultBehavior that implements BehaviorExtensionElement and IEndpointBehavior.  Below you will see the ApplyDispatchBehavior member from IEndpointBehavior.

public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
    EndpointDispatcher endpointDispatcher)
{
    SilverlightFaultMessageInspector inspector =
        new SilverlightFaultMessageInspector();
    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
}

As you can see in ApplyDispatchBehavior, it creates an instance of a type called SilverlightFaultMessageInspector (we’ll see that in a moment) and adds it to the MessageInspectors class of the dispatch runtime.  That inspector is doing the work of setting the status code to 200.  Take a look:

public class SilverlightFaultMessageInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request,
        IClientChannel channel, InstanceContext instanceContext)
    {
        return null;
    }

    public void BeforeSendReply(ref Message reply,
        object correlationState)
    {
        if (reply.IsFault)
        {
            HttpResponseMessageProperty property =
                new HttpResponseMessageProperty();
            property.StatusCode = System.Net.HttpStatusCode.OK;
            reply.Properties[HttpResponseMessageProperty.Name] = property;
        }
    }
}

If the reply is a fault, the status code is set to 200 (OK).  This will allow Silverlight 3 to see the fault.

Configuring the Service for the SilverlightFaultBehavior endpoint behavior

We need to update the web.config for our service to add this endpoint behavior.  Here is what we need to do:

  1. Add the extension (directly under System.ServiceModel)

    image
  2. Add the endpoint behavior (just below the serviceBehaviors node)

    image
  3. Add the behaviorConfiguration to the endpoint

    image

We are fully configured now.  When a FaultException is thrown, it will be sent across with a status code of 200.

Adding the FaultDetail

Remembering back, we want to enable sending a FaultException<T>.  What is the ‘T’ part?  We want to pass to the caller some information about the exception.  What I have chosen to send across in this sample is a Message, a “Type” and the RuleViolations collection. 

The “Type” will be a string that the client can use to determine what kind of exception it was.  ValidationExceptions will have a type of “ValidationException”, whereas, uncontrollable exceptions will be “TechnicalException”.  The RuleViolations collection will return all of the validation violations. Finally, the Message should be client-friendly (you should assume that the message will be directly exposed to the user.

namespace Silverlight.Patterns.Faults
{
    [DataContract]
    public class FaultDetail
    {
        [DataMember]
        public string Message { get; set; }

        [DataMember]
        public String Type { get; set; }

        [DataMember]
        public List<RuleViolation> RuleViolations { get; set; }
    }
}

 

Coding up the Service

Setting up the repository

I have my service configured the way I want it (set up to take advantage of binary encoding and FaultException<T>), so now I need to start writing the implementation.  We will start by introducing the concept of our repository to the service, and to provide a hook where we can adequately test the service operations without calling over http. 

The template stubs out a simple service operation called DoWork. We will delete that.  The next thing we want to do is to add a field for our ITicketRepository.  Next, I want to add a couple of constructors.  I want an overloaded constructor where I can pass in an ITicketRepository instance.  This will provide me a hook where I can pass in a FakeRepository for testing purposes.  I also want to implement the parameterless constructor that WCF will call.  This will set up the real repository for us.  See the code below:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TicketService
{
    ITicketRepository repository;

    public TicketService()
        : this(new TicketRepository())
    {

    }

    public TicketService(ITicketRepository theRepository)
    {
        repository = theRepository;
    }
}

Our test code can now call the overloaded constructor, passing in the Fake Repository.  Now we can move on to writing the operations.

Implementing the Fetch Operations

The fetch operations are pretty simple (because we have already implemented the repository and the pipeline.  Here they are:

[OperationContract()]
[FaultContract(typeof(FaultDetail))]
public List<Ticket> GetAllTickets()
{
    try
    {
        List<Ticket> tickets = repository.GetTickets().ToList();
        return tickets;
    }
    catch
    {
        FaultDetail detail = new FaultDetail();
        detail.Message = "An error occured returning the tickets";
        detail.Type = "TechnicalException";
        throw new FaultException<FaultDetail>(detail);
    }
}

[OperationContract()]
[FaultContract(typeof(FaultDetail))]
public List<Ticket> GetTicketPage(int pageNumber, int pageSize)
{
    try
    {
        List<Ticket> tickets = repository.GetTickets().ByPage(pageNumber, pageSize).ToList();
        return tickets;
    }
    catch
    {
        FaultDetail detail = new FaultDetail();
        detail.Message = "An error occured returning the tickets";
        detail.Type = "TechnicalException";
        throw new FaultException<FaultDetail>(detail);
    }
}

[OperationContract()]
[FaultContract(typeof(FaultDetail))]
public Ticket GetTicket(int ticketID)
{
    try
    {
        return repository.GetTickets().ByTicketID(ticketID);
    }
    catch
    {
        FaultDetail detail = new FaultDetail();
        detail.Message = "An error occured returning the ticket: " + ticketID.ToString();
        detail.Type = "TechnicalException";
        throw new FaultException<FaultDetail>(detail);
    }
}

[OperationContract()]
[FaultContract(typeof(FaultDetail))]
public List<SeverityLevel> GetAllSeverityLevels()
{
    try
    {
        return repository.GetSeverityLevels().ToList();
    }
    catch
    {
        FaultDetail detail = new FaultDetail();
        detail.Message = "An error occured returning the severity levels";
        detail.Type = "TechnicalException";
        throw new FaultException<FaultDetail>(detail);
    }
}

As you can see, in the event of an exception, we throw a FaultException, providing a FaultDetail.  In that FaultDetail, I am setting a client-friendly message, along with a Type of “TechnicalException”.  Notice that I have decorated each operation with a FaultContract, passing the type that will pass our error information back to the caller.

Implementing the Update Operation

The update operation is a bit more interesting.  Here is the code:

[OperationContract()]
[FaultContract(typeof(FaultDetail))]
public void UpdateTicket(Ticket ticket)
{
    Ticket t = repository.GetTickets().ByTicketID(ticket.TicketID);
    FaultDetail detail;

    try
    {
        //Merge the ticket
        t.ShortDescription = ticket.ShortDescription;
        t.LongDescription = ticket.LongDescription;
        t.IsOpen = ticket.IsOpen;
        t.SeverityLevelID = ticket.SeverityLevelID;
        IEnumerable<RuleViolation> vs = t.GetRuleViolations();
        repository.Save();
    }
    catch (ValidationException vexc)
    {
        detail = new FaultDetail();
        detail.Message = vexc.Message;
        detail.Type = "ValidationException";
        detail.RuleViolations = t.GetRuleViolations().ToList();
        throw new FaultException<FaultDetail>(detail);
    }
    catch
    {
        detail = new FaultDetail();
        detail.Message = "An unknown error occurred updating the ticket";
        detail.Type = "TechnicalException";
        throw new FaultException<FaultDetail>(detail);
    }
}

 

Remembering back to our OnValidate partial method that we added in our validation layer, it simply called IsValid to see if there are any RuleViolations.  If so, OnValidate threw an exception of type ValidationException.  In our update operation, we catch ValidationException.  In that block, we fetch the collection of rule violations and set the RuleViolations property on the FaultDetail.  In this way, we will pass back to Silverlight the server side validations that did not pass.

 

Testing Our Service Layer

As I mentioned earlier, by overloading the constructor of my service class, I left a hook in where I can easily test that layer without issuing an HTTP request.  I’m going to add a couple of tests now.  I am going to put these in a separate test class called TicketServiceTests.  You can see the code here:

TicketService CreateTicketService()
{
    var repository = Fakes.FakeTicketRepository.CreateFakeTicketRepository();
    return new TicketService(repository);
}

Above is a little helper method I created to new up my service class, passing in the FakeRepository.

[TestMethod]
public void Updating_A_Ticket_With_Empty_ShortDescription_Should_Cause_FaultException_Of_FaultDetail()
{
    // Arrange
    var service = CreateTicketService();

    // Act
    var ticket = service.GetTicket(1);
    ticket.ShortDescription = "";
    try
    {
        service.UpdateTicket(ticket);
        Assert.Fail("Validation Issue Should Have Occurred");
    }
    catch (FaultException<FaultDetail>)
    {
        Assert.IsTrue(true);
    }
    catch (Exception exc)
    {
        Assert.Fail("FaultException<FaultDetail> should have been thrown. " +
            exc.GetType().ToString() + " was thrown");
    }
}

Again, I have a very verbose method name.  You can see from this test that we are validating that the appropriate exception type is being thrown when a rule violation occurs.  The next test will ensure that the appropriate RuleViolation is returned with the exception.

[TestMethod]
//Added line break in Method name for blog readability
public void Updating_A_Ticket_With_Empty_ShortDescription_Should_Raise_FaultException_Of_
FaultDetail_Containing_RuleViolation_For_ShortDescription()
{
    // Arrange
    var service = CreateTicketService();

    // Act
    var ticket = service.GetTicket(1);
    ticket.ShortDescription = "";
    try
    {
        service.UpdateTicket(ticket);
        Assert.Fail("Validation Issue Should Have Occurred");
    }
    catch (FaultException<FaultDetail> ex)
    {
        Assert.IsInstanceOfType(
            ex.Detail.RuleViolations.Find(rv => rv.ErrorMessage ==
                Ticket.ShortDescriptionRequired),
                typeof(RuleViolation)
        );
    }
}

 

Summary

In this post, I added the services layer for my little sample app.  Here is a brief summary of what I did:

  1. Added a Web Application Project to the solution
  2. Used the ‘Silverlight-enabled WCF Service’ template to add a service configured with custom binding that wires up a binary encoder.
  3. I had to tidy up a bit.  I added a project and moved some re-usable components to that project.
  4. I added a SilverlightFaultBehavior class.  This will allow Silverlight to see our FaultExceptions.
  5. I update the web.config, configuring our SilverlightFaultBehavior class.
  6. I added a FaultDetail class.  This class allows me to pass info to the caller like a Message, the exception type and a collection of validation errors.
  7. I then coded up the service
    • I added an ITicketRepository field
    • I added the ability to set a fake repository with an overloaded constructor
    • I added the fetch operations
    • I added the update operation. In that operation, I caught the ValidationException. In that catch, I set the appropriate rule violations on the FaultDetail.
  8. I wrote some tests

 

What’s Next

In the next post, I will likely illustrate how the WCF service can be called from a Silverlight component.  I will also illustrate how we are able to pass across exceptions, as well as server-side validation issues.  The following post will get into the Service Agent pattern.

The Bagbys Are Moving to London

As some of you know, my wife Carrie works for American Express in Arizona.  Recently she was offered a great career opportunity in London and we have decided to pursue it.  It was a very difficult decision for us on many levels.  First and foremost, we are leaving behind our friends and family who mean the world to us.  Secondly, I have to leave my job with Microsoft and DPE (Developer and Platform Evangelism).  For over 3 years, I have had the privilege to work for the finest organization in the world with the best team I could imagine.  I am not embellishing when I tell you that for 3 years I have loved going to work.  This job will be hard to equal.

We are both looking forward to the adventure of living in another country, embracing another culture.  What you might not know is that Carrie and I met at Thunderbird, The American Graduate School of International Business, where we both earned Masters Degrees in International Finance.  I know what you’re thinking… Bagby? Finance?  I was young. I needed the money.  Seriously, Carrie and I have always had a passion for experiencing other cultures.  I spent a summer studying German at The University of Heidelberg and a winter in Vienna, while Carrie spent a summer studying Spanish in Spain.  Were a bit older now and not so quick on the uptake, so it is nice that we are moving somewhere where we already know the language.

Carrie has started her new job here in Arizona and has committed to being in London in early January.  As such, Carrie, Jack and I will heading “across the pond” sometime in early December.  I will continue in my current position until then.  I am not yet sure what I will be doing when we get to London.  Various opportunities have presented themselves thanks to the many friends I have made along the way at Microsoft. 

I’ll keep everyone apprised when things are more solid.

Watch the Windows 7 / Windows Server 2008 R2 Launch Virtually

Experience The New Efficiency Microsoft Launch Event Live from San Diego October 26th Virtually!
www.thenewefficiency.com/live

I, along with my teammates, will be delivering the Windows 7 / Windows Server 2008 R2 launch live from San Diego starting at 9am PDT October 26th. Now, you can view and download these 18 IT Professional and Developer focused sessions without ever leaving the house.  Focusing on Windows 7, Windows Server 2008 R2, and Exchange Server 2010, you can listen to Microsoft experts, download valuable resources and explore the live launch event "virtually".

Mark your calendars

« Previous PageNext Page »

Demystifying The Code