Using IErrorHandler and TCP Message Security timeout

I have a WCF service with a user connection IServiceBehavior used to return a specific client-side error. When I enable this code using TCP Message Security, I get a service timeout.

Below you can see the full client and server code to reproduce the error.

Server Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;

namespace TestWCFServer
{
    class program
    {
        static void Main (string [] args)
        {
            Console.WriteLine ("SERVER");

            NetTcpBinding binding = new NetTcpBinding ();
            binding.Security.Mode = SecurityMode.Message; // If you remove this line the code works !!!!

            Uri address = new Uri ("net.tcp: // localhost: 8184 /");

            // Create the ServiceHost.
            using (ServiceHost host = new ServiceHost (typeof (HelloWorldService)))
            {
                host.AddServiceEndpoint (typeof (IHelloWorldService), binding, address);

                host.Description.Behaviors.Add (new MyErrorhandlerBehavior ());

                host.Open ();

                Console.WriteLine ("The service is ready at {0}", address);
                Console.WriteLine ("Press to stop the service.");
                Console.ReadLine ();

                // Close the ServiceHost.
                host.Close ();
            }
        }
    }



    [ServiceContract]
    public interface IHelloWorldService
    {
        [OperationContract]
        string SayHello (string name);
    }

    public class HelloWorldService: IHelloWorldService
    {
        public string SayHello (string name)
        {
            if (name == null)
                throw new ArgumentNullException ("name");

            return string.Format ("Hello, {0}", name);
        }
    }

    class MyErrorhandlerBehavior: IServiceBehavior, IErrorHandler
    {
        #region IServiceBahvior
        public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher chanDisp in serviceHostBase.ChannelDispatchers)
            {
                chanDisp.ErrorHandlers.Add (this);
            }
        }

        public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }
        #endregion

        #region IErrorHandler Members
        public bool HandleError (Exception error)
        {
            return true;
        }

        public void ProvideFault (Exception error, MessageVersion ver, ref Message msg)
        {
            FaultException fe = new FaultException (error.Message);
            MessageFault fault = fe.CreateMessageFault ();
            msg = Message.CreateMessage (ver, fault, "net.tcp: // localhost: 8184 / fault");
        }
        #endregion
    }
}

Client Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace TestWCFClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("CLIENT");

            try
            {
                NetTcpBinding binding = new NetTcpBinding();
                binding.Security.Mode = SecurityMode.Message; //If you remove this line the code works!!!!

                Uri address = new Uri("net.tcp://localhost:8184/");
                EndpointAddress endpoint = new EndpointAddress(address);

                HelloWorldServiceClient client = new HelloWorldServiceClient(binding, endpoint);

                Console.WriteLine("Calling client with a valid parameter...");
                Console.WriteLine(client.SayHello("Davide"));
                Console.WriteLine("OK");

                Console.WriteLine("Calling client with an invalid parameter...");
                Console.WriteLine(client.SayHello(null)); //This call causes the timeout when Security is set to Message
                Console.WriteLine("OK");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }


            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
    }


    [ServiceContract]
    public interface IHelloWorldService
    {
        [OperationContract]
        string SayHello(string name);
    }

    class HelloWorldServiceClient : System.ServiceModel.ClientBase, IHelloWorldService
    {
        public HelloWorldServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress address) :
            base(binding, address)
        { }

        public string SayHello(string name)
        {
            return base.Channel.SayHello(name);
        }
    }
}

binding.Security.Mode = SecurityMode.Message; , , .

WCF :
"net.tcp://localhost: 8184/fault" .
.

, ? , / , , ... , , .

!

+5
2

, , , :

FaultContract OperationContract. .

, Action.

Sooooooooooo , , , .

+6

. ProvideFault :

public void ProvideFault(Exception error,MessageVersion ver, ref Message     
{
        FaultException fe = new FaultException(error.Message);
        MessageFault fault = fe.CreateMessageFault();
        msg = Message.CreateMessage(ver, fault, null);
}

null.

, .

+4

All Articles