简体   繁体   English

WCF如何全局处理错误

[英]WCF how to handle errors globally

So basically I want to handle exceptions in WCF services in centralized place. 因此,基本上我想在集中位置处理WCF服务中的异常。 For that I created a class that implements IErrorHandler and a class that implements IServiceBehavior and in that Service Behavior implementation I am saying that for each channel dispatcher I want to add my custom error handler like this. 为此,我创建了一个实现IErrorHandler的类和一个实现IServiceBehavior的类,并且在该Service Behavior实现中,我说的是,对于每个通道调度程序,我都希望添加这样的自定义错误处理程序。

public void ApplyDispatcherBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
    IErrorHandler errorHandler = new CustomErrorHandler();
    foreach (var channelDispatcher in serviceHostBase.ChannelDispatchers)
    {
        channelDispatcher.ErrorHandlers.Add(errorHandler);
    }
}

and the final thing that I've done is created a class that derives from a BehaviorExtensionElement with appropriate implementation and registered the extension in config file. 最后要做的是创建一个从BehaviorExtensionElement派生的类,该类具有适当的实现,并将扩展名注册在配置文件中。 but it does not seem to work. 但它似乎不起作用。 I mean that thing I want to do is if exception stays unhandled I want to handle it somewhere in a centralized place. 我的意思是,我想做的事情是如果异常未得到解决,我想在集中的地方处理它。 But it does not seem to work for me. 但这似乎对我不起作用。 Is my implementation correct, am I misunderstanding how this whole thing that I implemented should work. 我的实现正确吗,我误会了我实现的整个过程应该如何工作。 Any suggestion would be appreciated. 任何建议,将不胜感激。

<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
    <bindings>
      <basicHttpBinding>
        <binding name="soapBinding" />
      </basicHttpBinding>
      <webHttpBinding>
        <binding name="webBinding" />
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="poxBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="defaultBehavior">
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="MyCustomBehaviorExtensionElement" type="MyNamespace.CustomExtensionElement, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensions>
    <services>
      <service name="MyNamespace.MyService" behaviorConfiguration="defaultBehavior">
        <endpoint address="pox" binding="webHttpBinding" behaviorConfiguration="poxBehavior"
                  name="pox" contract="MyNamespace.IMyService" />
        <endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding"
                  name="soap" contract="MyNamespace.IMyService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/Services" />
          </baseAddresses>
        </host>
      </service>

here is the part of config file 这是配置文件的一部分

Missed in your web config 您的网络配置中缺少

In your case you haven't applied your extension, you need to add to your service behaviour your extension: 如果您尚未应用扩展程序,则需要将扩展​​程序添加到服务行为中:

  <serviceBehaviors>
    <behavior name="defaultBehavior">
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceMetadata httpGetEnabled="true" />

      <MyCustomBehaviorExtensionElement />
    </behavior>
  </serviceBehaviors>

WebHttpBinding: WebHttpBinding:

But, for handling error for WebHttpBinding you have to use such approach: 但是,要处理WebHttpBinding的错误,您必须使用以下方法:

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

namespace Server.Web
{
    public class WebHttpWithErrorHandlingElement : BehaviorExtensionElement
    {
        public class WebHttpWithErrorHandlingBehavior : WebHttpBehavior
        {
            internal sealed class WebHttpErrorHandler : IErrorHandler
            {
                private static readonly ILog logger = LogManager.GetLogger(typeof (WebHttpErrorHandler));

                public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
                {
                    var exception = new FaultException("Web Server error encountered. All details have been logged.");
                    var messageFault = exception.CreateMessageFault();

                    fault = Message.CreateMessage(version, messageFault, exception.Action);
                }

                public bool HandleError(Exception error)
                {
                    logger.Error(string.Format("An error has occurred in the Web service {0}", error));

                    return !(error is FaultException);
                }
            }

            protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            {
                base.AddServerErrorHandlers(endpoint, endpointDispatcher);

                endpointDispatcher.DispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(new WebHttpErrorHandler());
            }
        }

        public WebHttpWithErrorHandlingElement()
        {
        }

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

        protected override object CreateBehavior()
        {
            return new WebHttpWithErrorHandlingBehavior();
        }
    }
}

Config file: 配置文件:

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="webHttpWhithErrorHanlding" type="Server.Web.WebHttpWithErrorHandlingElement, Server.Web"/>
    </behaviorExtensions>
  </extensions>


  <!-- other staff -->
  <behaviors>
    <endpointBehaviors>
      <behavior name="webBehavior">
        <webHttpWhithErrorHanlding />
      </behavior>
    </endpointBehaviors>

  </behaviors>
</system.serviceModel>

And then apply it to your endpoint: 然后将其应用于您的端点:

  <service name="YourServiceContract">

    <endpoint address=""
              binding="webHttpBinding"
              behaviorConfiguration="webBehavior"
              contract="IYourServiceContract"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/"/>
      </baseAddresses>
    </host>        
  </service>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM