Ошибка Hadler EndPoint в моем хосте - WCF - Поведение - PullRequest
0 голосов
/ 04 апреля 2019

Несколько дней назад я открыл вопрос, если мне удастся получить ответы. Я не очень хорошо сфокусировал этот вопрос, и теперь с чем-то большим знанием спрашиваю снова.

Мне нужно зафиксировать ошибки всех моих конечных точек, чтобы они были включены в один и тот же сайт. Идея состоит в том, чтобы добавить поведение к этим конечным точкам.

namespace SIPE.Search.Helpers
{
    /// <summary>
    /// Implements methods that can be used to extend run-time behavior for an endpoint in either a client application.
    /// </summary>
    public class ExternalClientBehavior : BehaviorExtensionElement
    {
        protected override object CreateBehavior()
        {
            return new ExternalClientBehaviorClass();
        }

        public override Type BehaviorType
        {
            get
            {
                return typeof(ExternalClientBehaviorClass);
            }
        }

        /// <summary>
        /// JSON REST[GET] Converter Behavior
        /// </summary>
        private class ExternalClientBehaviorClass : IEndpointBehavior
        {
            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
            {                
            }

            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                ExternalClientMessageInspector clientInspector = new ExternalClientMessageInspector(endpoint);
                clientRuntime.MessageInspectors.Add(clientInspector);

                foreach (ClientOperation op in clientRuntime.Operations)
                {
                    op.ParameterInspectors.Add(clientInspector);
                }
            }

            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            {
                //("Behavior not supported on the consumer side!");
            }

            public void Validate(ServiceEndpoint endpoint)
            {

            }
        }

    }
}

Теперь я знаю, что он никогда не войдет в мой ApplyDispatchBehaviour, если клиент не реализует мое поведение, и это НИКОГДА не произойдет, так как они являются внешними поставщиками, и у меня нет доступа к коду.

Кроме того, моя первая ошибка даже не покидает мой код, поскольку я вызываю ошибку NOT FOUND.

Я нашел много похожих источников с моей проблемой без решения. Я нашел на нескольких сайтах добавить следующее в ApplyClientBehaviour:

IErrorHandler errorHandler = new CustomErrorHandler();
clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(errorHandler);

Но это не работает.

Другие источники, которые произошли со мной: https://riptutorial.com/csharp/example/5460/implementing-ierrorhandler-for-wcf-services

Это НЕ решение, так как оно относится к поведению служб. Мне нужно сделать это в EndPoint Behavior.

Спасибо

1 Ответ

0 голосов
/ 05 апреля 2019

Пожалуйста, обратитесь к следующему примеру.
Серверная сторона.

class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:1100");
            BasicHttpBinding binding = new BasicHttpBinding();
            using (ServiceHost sh = new ServiceHost(typeof(MyService), uri))
            {
                ServiceEndpoint se = sh.AddServiceEndpoint(typeof(IService), binding, "");
                ServiceMetadataBehavior smb;
                smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null)
                {
                    smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                    smb.HttpGetUrl = new Uri("http://localhost:1100/mex");
                    sh.Description.Behaviors.Add(smb);
                }
                MyEndpointBehavior bhv = new MyEndpointBehavior();
                se.EndpointBehaviors.Add(bhv);


                sh.Open();
                Console.WriteLine("service is ready");
                Console.ReadKey();
                sh.Close();
            }
        }
    }
    [ServiceContract(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, error.Message);
        }
    }
    public class MyEndpointBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            return;
        }

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

        public void Validate(ServiceEndpoint endpoint)
        {
            return;
        }
}

Клиент.

static void Main(string[] args)
{
    ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
    try
    {
        client.Delete(-3);
    }
    catch (FaultException fault)
    {
        Console.WriteLine(fault.Reason.GetMatchingTranslation().Text);
    }
}

Результат.
enter image description here
Не стесняйтесь, дайте мне знать, если есть что-то, с чем я могу помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...