0
votes

1)In my windows application client, call the multiple wcf services using the ChannelFactory method. In one of client method call the multiple service one by one, after idle timeout I create a channel for one service object whenever Faulted event fire but how can i maintain the other service channel which is also faulted the same time? Or in More simple words 2)In my windows application client, consume the wcf service using the ChannelFactory method, can i catch the Faultexception in service factory class where i am creating the channel for that service?

1

1 Answers

0
votes

Generally speaking, we could use the FaultException class to capture the exceptions thrown by the server side.

Server.

public class MyService : IService
    {
        public string SayHello(int value)
        {
            if (value<=0)
            {
                throw new FaultException("Parameter should be greater than 0");
            }
            return "Hello Stranger";
        }
}

Client.

ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, new EndpointAddress(uri));
            IService service = factory.CreateChannel();
            try
            {
                Console.WriteLine(service.SayHello(0));
            }
            catch (FaultException ex)
            {
                FaultReason reason = ex.Reason;
                Console.WriteLine(reason.GetMatchingTranslation().Text);
            }

In this way, the exception thrown by the server can be correctly captured by the client. If we need to unify all the errors thrown by the server, we could implement the IErrorhandler interface and write custom error handling classes. I have made a demo wish it is useful to you.

Server.

class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:1000");
            ServiceHost sh = new ServiceHost(typeof(MyService), uri);
            sh.Open();
            Console.WriteLine("service is ready");
            Console.ReadKey();
            sh.Close();
        }
    }
    [ServiceContract(Namespace ="mydomain",ConfigurationName ="isv")]
    public interface IService
    {
        [OperationContract]
        string Delete(int value);
        [OperationContract]
        void UpdateAll();
    }
    [ServiceBehavior(ConfigurationName = "sv")]
    public class MyService : IService
    {
        public string Delete(int value)
        {
            if (value<=0)
            {
                throw new ArgumentException("Parameter should be greater than 0");
            }
            return "Hello";
        }

        public void UpdateAll()
        {
            throw new InvalidOperationException("Operation exception");
        }
    }
    public class MyCustomErrorHandler : IErrorHandler
    {
        public bool HandleError(Exception error)
        {
            return true;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            FaultException faultException = new FaultException(error.Message);
            MessageFault messageFault = faultException.CreateMessageFault();
            fault = Message.CreateMessage(version, messageFault,"my-error");
        }
}
//only need to implement the ApplyDispatchBehavior method.
    public class MyEndpointBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            throw new NotImplementedException();
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            throw new NotImplementedException();
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            MyCustomErrorHandler myCustomErrorHandler = new MyCustomErrorHandler();
            endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(myCustomErrorHandler);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            throw new NotImplementedException();
        }
}

Client.

class Program
    {
       static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:1000");
            BasicHttpBinding binding = new BasicHttpBinding();
            ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, new EndpointAddress(uri));
            IService service = factory.CreateChannel();
            try
            {
                Console.WriteLine(service.Delete(0));
                Console.ReadKey();
            }
            catch (FaultException ex)
            {
                FaultReason reason = ex.Reason;
                Console.WriteLine(reason.GetMatchingTranslation().Text);
            }
            try
            {
                service.UpdateAll();
            }
            catch (FaultException ex)
            {
                Console.WriteLine(ex.Reason.GetMatchingTranslation().Text);
            }
        }
    }
    [ServiceContract(Namespace = "mydomain", ConfigurationName = "isv")]
    public interface IService
    {
        [OperationContract]
        string Delete(int value);
        [OperationContract]
        void UpdateAll();
    }

Result Image

Here is Official document