我已经阅读了所有有关此内容的内容,但也许我错过了一些东西(嗯,绝对是我缺少了一些东西,否则它已经可以工作了)

我在服务器业务层内抛出一些异常错误:

public class RfcException :  Exception
{
   public RfcException(string _m, Exception _inner) : base(_m, _inner)
   { }

   public Dictionary<string, string> ExtendedProperties
   {
      get { return extendedProperties; }
      protected set { extendedProperties = value; }
   }

   private Dictionary<string, string> extendedProperties = new Dictionary<string, string>();
}

我没有在服务中处理它,但是我有一个IErrorHandler可以捕获并创建一个FaultMessage:
public class FaultErrorHandler : BehaviorExtensionElement, IErrorHandler, IServiceBehavior
{
   public bool HandleError(Exception error)
   {
      if (!Logger.IsLoggingEnabled()) return true;
      var logEntry = new LogEntry
        {
           EventId = 100,
           Severity = TraceEventType.Error,
           Priority = 1,
           Title = "WCF Failure",
           Message = string.Format("Error occurred: {0}", error)
        };
      logEntry.Categories.Add("MiddleTier");

      Logger.Write(logEntry);
      return true;
   }

   public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
   {
      if (error is RfcException)
      {
         RfcException rfcException = error as RfcException;
         var serviceFault = new RfcServiceFault(rfcException);
         var faultException = new FaultException<RfcServiceFault>(serviceFault, new FaultReason(string.Format("System error occurred, exception: {0}", error)));
         var faultMessage = faultException.CreateMessageFault();
         fault = Message.CreateMessage(version, faultMessage, Schema.WebServiceStandard);
      }
      else
      {
         var faultException = new FaultException<Exception>(error, new FaultReason(string.Format("System error occurred, exception: {0}", error)));
         var faultMessage = faultException.CreateMessageFault();
         fault = Message.CreateMessage(version, faultMessage, Schema.WebServiceStandard);
      }
   }

   public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
   { }

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

   public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
   { }

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

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

不用问了我已经通过调试器确认了它在if (error is RfcException)部分中的输入,我已经逐步完成了该代码,并且直到最后都没有任何麻烦。
该errorHandler包装FaultException<RfcServiceFault>消息,RfcServiceFault消息是这个
[DataContract(Name = "RfcServiceFault", Namespace = "Service.DataTransfer.Rfc")]
public class RfcServiceFault
{
   public RfcServiceFault(RfcException rfcException) : this( (Exception)rfcException )
   {
      ExtendedProperties = new Dictionary<string, string>(rfcException.ExtendedProperties);
   }

   public RfcServiceFault()
   { }

   public RfcServiceFault(Exception regularException)
   {
      FaultMessage = regularException.Message;
      StackTrace = regularException.StackTrace;
   }

   public Dictionary<string, string> ExtendedProperties
   {
      get { return extendedProperties; }
      protected set { extendedProperties = value; }
   }

   [DataMember]
   private Dictionary<string, string> extendedProperties = new Dictionary<string, string>();

   [DataMember]
   public string FaultMessage { get; set; }

   [DataMember]
   public string StackTrace { get; set; }
}

该服务具有应该带有带有faultContract的wcf服务的所有注释:
[ServiceContract(Name = "MyService", Namespace = Schema.WebServiceStandard, SessionMode = SessionMode.Allowed)]
public interface IMyService
{
    [OperationContract(Name = "GetStuff")]
    [FaultContract(typeof(RfcServiceFault) , Name="RfcServiceFault", Namespace="Service.DataTransfer.Rfc")]
    LookupResult GetStuff();
}

现在:在客户端进行测试,像这样的简单测试:
try
{
   var result = myService.GetStuff();
   Assert.IsTrue(!string.IsNullOrEmpty(result));
}
catch (FaultException<RfcServiceFault> rfcEx)
{
   // OMG FOR THE LIFE OF THE PUPPIES ENTER HERE
}
catch (FaultException rr)
{
   // it always falls in here
}
catch (Exception ex)
{ }

我读过很多关于这个类似问题的文章:
  • Cannot handle FaultException
  • Throwing generic FaultException
  • c# WCF catch Fault Exceptions of Base type
  • WCF: WSDL-first approach: Problems with generating fault types

  • 但到目前为止似乎没有任何帮助,我尝试在web.config中设置WCF跟踪:
    <system.diagnostics>
        <sources>
          <source name="System.ServiceModel"
                  switchValue="Information, ActivityTracing">
            <listeners>
              <add name="log"
                   type="System.Diagnostics.XmlWriterTraceListener"
                   initializeData="c:\Traces.svclog" />
            </listeners>
          </source>
        </sources>
      </system.diagnostics>
    

    我在那里得到一个svclog文件,使用WCF Trace查看器打开,但是我只看到一堆消息,黄色的消息显示了Exception,但是它仅确认客户端已经看到的内容,而不是接收到的System.ServiceModel.FaultException,而不是通用的

    任何想法如何解决这个问题?

    编辑忘了提,我在配置中启用了我的错误处理程序,如下所示:
    <behaviorExtensions>
       .....
        <add name="faultErrorHandlerBehavior"
             type="Service.FaultErrorHandler,Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        .....
    </behaviorExtensions>
    <serviceBehaviors>
       <behavior name="ServiceBehavior">
           <serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="200"
                              maxConcurrentInstances="200" />
           <serviceMetadata httpGetEnabled="true" />
           <serviceDebug includeExceptionDetailInFaults="true" />
           <faultErrorHandlerBehavior />
        </behavior>
    </serviceBehaviors>
    

    最佳答案

    (这在黑暗中有点刺痛)我相信您可能会遇到问题,因为针对故障的操作与客户端预期的操作不匹配。您能否将CreateMessage替换为以下内容:

    fault = Message.CreateMessage(version, faultMessage, faultException.Action);
    

    10-06 05:34