16

私はこれについて読むためにそこにあるすべてを読みました、しかし多分私は何かを逃しています(まあ、確かに私は何かを逃しています、さもなければそれはすでに働いているでしょう)

サーバービジネスレイヤー内でいくつかの例外エラーをスローしています:

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)
{ }

私はこの同様の問題に関する多くの投稿を読みました:

しかし、これまでのところ何も役に立たないようです。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トレースビューアーで開きますが、一連のメッセージのみが表示され、黄色のメッセージは例外を示しますが、クライアントがすでに表示しているもの、つまり受信されているものを確認するだけ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>
4

1 に答える 1

15

(これは暗闇の中でのちょっとした刺し傷です)障害に対するアクションがクライアントで期待されるアクションと一致しないため、問題が発生している可能性があると思います。CreateMessageを次のように置き換えてください。

fault = Message.CreateMessage(version, faultMessage, faultException.Action);
于 2011-07-06T08:57:58.683 に答える