4

IErrorHandlerインターフェイスを機能させるのに問題があるようです。私のコードは

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace WcfService3
{
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            throw new Exception("asdf");

        }
    }

    public class MyErrorHandler : IErrorHandler
    {
        public MyErrorHandler()
        {
            string Hello = "";
        }
        public bool HandleError(Exception error)
        {
            return true;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
        {
            var vfc = new MyFault();
            var fe = new FaultException<MyFault>(vfc);
            var fault = fe.CreateMessageFault();
            msg = Message.CreateMessage(version, fault, "http://ns");
        }
    }

    public class ErrorHandlerExtension : BehaviorExtensionElement, IServiceBehavior
    {
        public override Type BehaviorType
        {
            get { return GetType(); }
        }

        protected override object CreateBehavior()
        {
            return this;
        }

        private IErrorHandler GetInstance()
        {
            return new MyErrorHandler();
        }

        void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }

        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandlerInstance = GetInstance();
            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(errorHandlerInstance);
            }
        }

        void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
            {
                if (endpoint.Contract.Name.Equals("IMetadataExchange") &&
                    endpoint.Contract.Namespace.Equals("http://schemas.microsoft.com/2006/04/mex"))
                    continue;

                foreach (OperationDescription description in endpoint.Contract.Operations)
                {
                    if (description.Faults.Count == 0)
                    {
                        throw new InvalidOperationException("FaultContractAttribute not found on this method");
                    }
                }
            }
        }
    }
}

私のweb.configは次のとおりです。

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
      <services>
    <service name="WcfService3.Service1">
      <endpoint address=""
                binding="basicHttpBinding"
                contract="WcfService3.IService1" />
    </service>
  </services>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
      <extensions>
    <behaviorExtensions>
      <add name="errorHandler"
            type="WcfService3.ErrorHandlerExtension, WcfService3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </behaviorExtensions>
  </extensions>

    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

私のWCFインターフェースは次のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService3
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [FaultContract(typeof(MyFault))]
        string GetData(int value);
    }

    [DataContract]
    public class MyFault
    {

    }

}

私の質問は、WCF の IErrorHandler にあります。WCF サービス呼び出し中に例外が発生した場合HandlerError()、C# Windows アプリケーションの UnhandledException クラスのように関数が最初に呼び出され、サービスが正しくクラッシュするはずです。上記のコードでは、サービス呼び出し中に例外がスローされますがHandlerError、例外がスローされる前に関数が呼び出されませんか? 私の目標はエラーをログに記録することであり、WCF サービスは未処理の例外をスローしてクラッシュする可能性があります。デバッグ中にブレークポイントが HandleError 関数を訪問することを期待していましたが、その関数が呼び出されず、例外が表示されただけですか?

4

2 に答える 2

3

<errorHandler />あなたのbehaviorセクションが欠けていませんか?

<behavior>
    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="false"/>
    <!-- HERE -->
    <errorHandler />
    <!-- HERE -->
</behavior>

完全な答えはここにあります。その答えにプラス1。

于 2013-07-10T20:57:21.457 に答える
0

他の誰かがこれに遭遇した場合、私がこのエラーに遭遇したのは、何らかの LINQ 式から呼び出されたメソッドでエラーがスローされたためでした。このメソッドは、WCF が応答をシリアル化しようとするまで実際には呼び出されず、サービス スコープの外にスローされました。WCF は、これらのエラーを IErrorHandler に渡しません。

.ToList() を使用して戻る前にリストを具体化すると、この問題が解決しました。

于 2018-08-02T19:36:05.573 に答える