You can use an IErrorHandler to accomplish that:
Client.cs:
class Program
{
[DataContract]
public enum MyDCServer
{
[EnumMember]
Test = 0
}
[ServiceContract]
public interface ITestServer
{
[OperationContract]
[FaultContract(typeof(string))]
MyDCServer EchoDC(MyDCServer input);
}
static Binding GetBinding()
{
BasicHttpBinding result = new BasicHttpBinding();
return result;
}
static void Main(string[] args)
{
string baseAddress = "http://localhost:8000/Service";
ChannelFactory<ITestServer> factory = new ChannelFactory<ITestServer>(GetBinding(), new EndpointAddress(baseAddress));
ITestServer proxy = factory.CreateChannel();
MyDCServer uu = proxy.EchoDC(MyDCServer.Test);
Console.WriteLine(uu);
Console.ReadKey();
}
}
The value transmitted by the client is Test.
Server.cs:
public class Post
{
[DataContract]
public enum MyDCServer
{
[EnumMember]
BMW = 0,
[EnumMember]
Honda = 1,
[EnumMember]
Tesla = 2
}
[ServiceContract]
public interface ITestServer
{
[OperationContract]
[FaultContract(typeof(string), Action = Service.FaultAction)]
MyDCServer EchoDC(MyDCServer input);
}
public class Service : ITestServer
{
public const string FaultAction = "http://my.fault/serializationError";
public MyDCServer EchoDC(MyDCServer input)
{
Console.WriteLine(input);
return input;
}
}
public class MyErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return error is FaultException && (error.InnerException as SerializationException != null);
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
if (error is FaultException)
{
SerializationException serException = error.InnerException as SerializationException;
if (serException != null)
{
string detail = String.Format("{0}: {1}", serException.GetType().FullName, serException.Message);
FaultException<string> faultException = new FaultException<string>(detail, new FaultReason("CarBrand should be BMW, Honda or Tesla"));
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, Service.FaultAction);
}
}
}
}
public class MyServiceBehavior : IServiceBehavior
{
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher disp in serviceHostBase.ChannelDispatchers)
{
disp.ErrorHandlers.Add(new MyErrorHandler());
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
{
if (endpoint.Contract.ContractType == typeof(IMetadataExchange)) continue;
foreach (OperationDescription operation in endpoint.Contract.Operations)
{
FaultDescription expectedFault = operation.Faults.Find(Service.FaultAction);
if (expectedFault == null || expectedFault.DetailType != typeof(string))
{
throw new InvalidOperationException("Operation must have FaultContract(typeof(string))");
}
}
}
}
}
static Binding GetBinding()
{
BasicHttpBinding result = new BasicHttpBinding();
return result;
}
static void Main(string[] args)
{
string baseAddress = "http://localhost:8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITestServer), GetBinding(), "");
host.Description.Behaviors.Add(new MyServiceBehavior());
host.Open();
Console.WriteLine("Host opened");
Console.ReadLine();
host.Close();
}
}
And there is no Test in the enumeration type of the server.
When the client calls, it will get the following exception information:

The code above is referenced from this link;
UPDATE:
We can use serException.TargetSite.Name to determine whether an enumeration type serialization exception has occurred:
if (serException != null&& serException.TargetSite.Name== "ReadEnumValue")
{
string detail = String.Format("{0}: {1}", serException.GetType().FullName, serException.Message);
FaultException<string> faultException = new FaultException<string>(detail, new FaultReason("CarBrand should be BMW, Honda or Tesla"));
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, Service.FaultAction);
}
For how to apply MyServiceBehavior in the configuration file, you can refer to this link.
You can also use Attribute to apply MyServiceBehavior to the service:
public class MyServiceBehavior : Attribute,IServiceBehavior
{...
