I know this question has been asked on a number of occassions (believe me I know I have went through almost every one of the posts). However, I still can't get it to work...
I have the following simple service:
[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebGet(UriTemplate = "/data/{id}", ResponseFormat = WebMessageFormat.Json)]
    [FaultContract(typeof(CustomError))]
    Data GetData(string id);
}
[DataContract]
public partial class Data
{
    [DataMember]
    public string Property { get; set; }
}
[DataContract]
public class CustomError
{
    [DataMember]
    public string Message { get; set; }
}
In the implementation of the GetData is as follows:
public Data GetData(string id)
{
    int dataId = -1;
    if (!Int32.TryParse(id, out dataId))
    {
        var detail = new CustomError() { Message = "DataID was not in the correct format."};
        throw new FaultException<CustomError>(detail);
    }
    ... return instance of Data
}
If I pass a valid ID in I get the approprate Data object coming across the wire, however, if I pass an invalid ID in (to trigger the FaultException) it always comes over to the client as a ProtocolException with the same message: 
The remote server returned an unexpected response: (400) Bad Request.
I initially went down the road of implementing IErrorHandler and this is where I started getting the issue so to eliminate that from the equation, I implemented this basic service... but I can't even get it to work.
On my client I have created a Service Reference and using the client proxy i.e.
using (var client = new DataServiceClient())
{
    try
    {
        var user = client.GetData("twenty");
        Console.WriteLine(user.Property);
    }
    catch (System.ServiceModel.FaultException<CustomError> ex)
    {
        Console.WriteLine(ex.Message);
    }
}
Is there something I am missing? (I can post the Service/Client configuration settings on request)
NB: I noticed that when you add a service reference and it generates the client proxy (I am on VS2010) you need to manually add the WebGet/WebInvoke attribute to the generated client as it doesn't seem to come over automatically.
 
     
     
    