Контроль ошибок / обработчик (захват) с поведением в wcf.Бизнес уровень - PullRequest
0 голосов
/ 25 марта 2019

У меня есть проект (бэкэнд), в котором он получает вызов на уровне сервиса, но он также выполняет вызовы другого API на бизнес-уровне.

Я добавил поведение к этим вызовам, поэтому мне не нужно вносить изменения в несколько мест в моем коде.

My Behaviour.config (импорт - ExternalDependencyBehavior):

<?xml version="1.0" encoding="utf-8"?>
<behaviors>
  <endpointBehaviors>
    <!-- SPECIFIC BEHAVIOR EXTENSION FOR JSON URL DESERIALIZER-->
    <behavior name="ServiceRESTBehavior">
      <ConverterWebHttpBehaviourExtension />
    </behavior>
    <behavior name="ServiceSOAPBehavior" />
    <behavior name="ExternalDependencyBehavior">
      <ExternalClientBehavior/>
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="DefaultBehaviour">
      <serviceMetadata httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>  
</behaviors>

Мой код: (один метод на бизнес-уровне, который вызывает другой внешний API)

protected virtual Vendor.Sinacofi.SinacofiService.RespuestaSNPV1201 RequestToVendor(VendorWebService vendor, string clientFiscalId, BasicSearchCriterion criteria)
{
    Vendor.Sinacofi.SinacofiService.RespuestaSNPV1201 result = new Vendor.Sinacofi.SinacofiService.RespuestaSNPV1201();
    string errorLogProvider = null;

    try
    {
       using (Vendor.Sinacofi.SinacofiService.SNPV1201SoapClient client = new Vendor.Sinacofi.SinacofiService.SNPV1201SoapClient())
       {
        /*Credentials*/
        result = client.ConsultaRutificacion(
                client.ClientCredentials.HttpDigest.ClientCredential.UserName,
                client.ClientCredentials.HttpDigest.ClientCredential.Password,
                clientFiscalId,
                criteria.Value
            );
        }
    return result;
    }
    catch (AxrException)
    {
        throw;
    }
    catch (FaultException fex)
    {
        this.logProvider.WriteInErrorMode(GetType().Name, MethodBase.GetCurrentMethod().Name, fex);
        throw this.exceptionProvider.Create(ErrorCode.---------, ExceptionType.BUSINESS, fex);
    }
    catch (Exception ex)
    {
        this.logProvider.WriteInErrorMode(GetType().Name, MethodBase.GetCurrentMethod().Name, ex);
        throw this.exceptionProvider.Create(ErrorCode.-------------, ExceptionType.BUSINESS, ex);
    }
}

В итоге:

Когда я приеду на звонок: "Client.ConsultaRutification"

Мое поведение выполняется, я добавляю код (2 файла):

using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

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)
            {
                endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new ExternalClientMessageInspector(endpoint));
            }

            public void Validate(ServiceEndpoint endpoint)
            {

            }
        }

    }
}

И файл два:

namespace SIPE.Search.Helpers
{
    /// <summary>
    /// Intercepts send requests. 
    /// </summary>
    public class ExternalClientMessageInspector : IClientMessageInspector, IParameterInspector, IErrorHandler
    {
        private ServiceEndpoint Endpoint { get; set; }

        Dictionary<string, object> inputsParam;

        public ExternalClientMessageInspector(ServiceEndpoint endpoint)
        {
            //empty
        }

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            ((Dictionary<string, string>)(System.Web.HttpContext.Current.Items[operationName])).Add("OutputParam", JsonConvert.SerializeObject(returnValue));

        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            //code not necessary
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            // code not neccesary
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
            Message copy = buffer.CreateMessage();  // Create a copy to work with
            request = buffer.CreateMessage();         // Restore the original message

            return copy.GetReaderAtBodyContents().Name;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            // no implement
        }

        public bool HandleError(Exception error)
        {
            // no implement
            return true;
        }

        public void NotifyError()
        {

        }
    }
}

Мне нужно иметь возможность фиксировать ошибки (например, 404 и другие) моих вызовов в моем поведении. Я попытался добавить несколько интерфейсов, но безуспешно

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

спасибо

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