Archive

Archive for November, 2010

Extension method fun

November 6, 2010 Leave a comment

During programming, I had the recurring need to find the positions of elements in a collection that satisfied a certain condition. Because duplication is evil, I wrote a small generic extension method to handle this.

public static class EnumerableExtensions
{
    public static IEnumerable<int> IndexesOf<T>(this IEnumerable<T> enumerable, Func<T, bool> predicate)
    {
        IEnumerable<KeyValuePair<T, int>> keyValuePairs =
            enumerable.Select((item, index) => new KeyValuePair<T, int>(item, index));
        return keyValuePairs.Where(keyValue => predicate(keyValue.Key)).Select(keyValue => keyValue.Value);
    }
}

A small demo application, if you want to try it out:

class Program
{
    static void Main(string[] args)
    {
        string[] array = new string[] { "pieter", "bill", "steve", "philippe" };
        IEnumerable<int> indexes = array.IndexesOf(n => n.StartsWith("p"));

        Console.WriteLine("Indexes of names that start with a \"p\":");
        foreach (int index in indexes)
        {
            Console.WriteLine(index);
        }

        Console.ReadLine();
    }
}
Advertisements
Categories: C#

Throwing a WCF FaultException to a Service Moniker based client

November 2, 2010 Leave a comment

Introduction

Soap supports the notion of a Fault. This allows a web service to notify a client that an unexpected error has occurred during processing on the server. You should use this SOAP feature with care, because it could couple the client and the server together if it not carefully used. Yet in service oriented architectures, you want to decouple clients and servers as much as possible. Providing to much information about the error, like for example the server side stack trace, also introduces a security hole. But If Faults are used with care they provide an added value to web services.

WCF supports two types of Faults; generic faults implemented by FaultException and non generic faults implemented by FaultException<T>. The generic version essentially sends a string as fault payload back to the client, while the non generic version allows to specify a DataContract.

I recently discovered that the WCF service moniker supports the generic FaultException. In this article example, I will explain you how to implement it.

If you want more information about the WCF service moniker for COM based applications, please see my previous article:

https://pieterderycke.wordpress.com/2010/10/05/using-a-service-moniker-to-communicate-between-legacy-com-applications-and-new-net-applications/

Service Implementation

We are going to create a very simple WCF service, that accepts a string and that will throw the contents of the string as Fault back to the client.

The service interface:

namespace ServiceMonikerFaultsService
{
    [ServiceContract]
    public interface IFaultService
    {
        [OperationContract]
        void ThrowFault(string message);
    }
}

The service implementation:

namespace ServiceMonikerFaultsService
{
    public class FaultService : IFaultService
    {
        public void ThrowFault(string message)
        {
            throw new FaultException(message);
        }
    }
}

The service configuration in the web.config:

<system.serviceModel>
  <services>
    <service name="ServiceMonikerFaultsService.FaultService"
              behaviorConfiguration="serviceBehavior">
      <endpoint address=""
                binding="wsHttpBinding"
                contract="ServiceMonikerFaultsService.IFaultService"/>
      <endpoint address="mex"
                binding="mexHttpBinding"
                contract="IMetadataExchange" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="serviceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

You can now press F5 to launch your WCF service.

Client Implementation

We can now launch Excel to create a simple VBA client for our service, but of course you can call this service from every COM based program.

Our client code:

Sub ServicemonkercallMex()
    Dim service As Object
    Dim monString As String

    monString = "service4:mexaddress=http://localhost:49161/FaultService.svc/mex" & _
                ", address=http://localhost:49161/FaultService.svc" & _
                ", contract=IFaultService, contractNamespace=http://tempuri.org/" & _
                ", binding=WSHttpBinding_IFaultService, bindingNamespace=http://tempuri.org/"

    Set service = GetObject(monString)

    On Error GoTo HandleError:
    service.ThrowFault "A WCF Fault thrown to Excel"
    Exit Sub

HandleError:
    MsgBox Err.Description, vbCritical, "Error"
End Sub

Please do not forget to change the service address to the address of the WCF service on your local pc.

When we press F5 to launch the VBA code, we get the following response back from the WCF service:

wcf_excel_error

Conclusion

FaultExceptions are the WCF mechanism to propagate exceptions from the service to the client. WCF supports both generic and non generic FaultExceptions. Generic FaultExceptions can only transmit a string value to the client, non generic FaultExceptions can transmit a DataContract. Unfortunately, the WCF Service Moniker only supports the generic version.

Categories: C#, WCF