本文介绍了客户端不会赶上普通的FaultException< T&GT ;,唯一的FaultException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过所有有这个阅读,但也许我失去了一些东西(当然,肯定是我想的东西,否则这将是已经工作)



我要把我的服务器业务层内部的一些异常错误:

 公共类RfcException:异常
{
公共RfcException(字符串_m,异常_inner):基地(_m,_inner)
{}

公众解释<字符串,字符串> ExtendedProperties
{
{返回extendedProperties; }
保护集合{extendedProperties =价值; }
}

私人字典<字符串,字符串> extendedProperties =新词典<字符串,字符串>();
}



这是我的服务,将未处理的,但我有一个 IErrorHandler 来捕获并创建一个 FaultMessage

 公共类FaultErrorHandler:BehaviorExtensionElement,IErrorHandler,IServiceBehavior接口
{
公共BOOL的HandleError(异常错误)
{
如果返回true;(Logger.IsLoggingEnabled()!)
变种logEntry =新LogEntry
{
EVENTID = 100,
严重性= TraceEventType.Error,
优先级= 1,
标题=WCF失败 ,
消息=的String.Format(发生错误:{0},错误)
};
logEntry.Categories.Add(MiddleTier);

Logger.Write(logEntry);
返回真;
}

公共无效ProvideFault(异常错误,System.ServiceModel.Channels.MessageVersion的版本,文献System.ServiceModel.Channels.Message故障)
{
如果(错误RfcException)
{
RfcException rfcException =误差RfcException;
变种serviceFault =新RfcServiceFault(rfcException);
变种的FaultException =新的FaultException< RfcServiceFault>(serviceFault,新FaultReason(的String.Format(发生系统错误,异常:{0},错误)));
VAR faultMessage = faultException.CreateMessageFault();
故障= Message.CreateMessage(版本,faultMessage,Schema.WebServiceStandard);
}
,否则
{
变种的FaultException =新的FaultException<异常>(错误,新FaultReason(的String.Format(系统出错,异常:{0},错误)));
VAR faultMessage = faultException.CreateMessageFault();
故障= Message.CreateMessage(版本,faultMessage,Schema.WebServiceStandard);
}
}

公共无效AddBindingParameters(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase,System.Collections.ObjectModel.Collection< ServiceEndpoint>端点,System.ServiceModel.Channels。 BindingParameterCollection bindingParameters)
{}

公共无效ApplyDispatchBehavior(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase)
{
的foreach(ChannelDispatcher chanDisp在serviceHostBase.ChannelDispatchers)
{
chanDisp.ErrorHandlers.Add(本);
};
}

公共无效验证(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase)
{}

公众覆盖类型BehaviorType
{
{返回的typeof(FaultErrorHandler); }
}

保护覆盖对象CreateBehavior()
{
返回新FaultErrorHandler();
}
}

没有必要问;我已经使用调试器证实了其在部分如果(误差RfcException)部分进入,我已经通过代码加强,并达到直到没有任何麻烦的结束。
那的ErrorHandler包装了一个的FaultException< RfcServiceFault> 消息,在 RfcServiceFault 的消息是这样的。



  [DataContract(NAME =RfcServiceFault,命名空间=Service.DataTransfer.Rfc)] 
公共类RfcServiceFault
{
公共RfcServiceFault(RfcException rfcException):这个((例外)rfcException)
{
ExtendedProperties =新词典<字符串,字符串>(rfcException.ExtendedProperties);
}

公共RfcServiceFault()
{}

公共RfcServiceFault(例外regularException)
{
FaultMessage = regularException。信息;
堆栈跟踪= regularException.StackTrace;
}

公众解释<字符串,字符串> ExtendedProperties
{
{返回extendedProperties; }
保护集合{extendedProperties =价值; }
}

[数据成员]
私人字典<字符串,字符串> extendedProperties =新词典<字符串,字符串>();

[数据成员]
公共字符串FaultMessage {搞定;组; }

[数据成员]
公共字符串堆栈跟踪{搞定;组; }
}



该服务拥有所有应该有一个WCF服务与faultContract注释

  [的ServiceContract(名称=则将MyService,命名空间= Schema.WebServiceStandard,SessionMode = SessionMode.Allowed)] 
酒店的公共接口IMyService
{
[OperationContract的(名称=一个getStuff)]
[FaultContract(typeof运算(RfcServiceFault),名称=RfcServiceFault,命名空间=Service.DataTransfer.Rfc )]
LookupResult GetStuff();
}

立即是在客户端测试,简单试验是这样的:

 
{
VAR的结果= myService.GetStuff();
Assert.IsTrue(string.IsNullOrEmpty(结果)!);
}
赶上(FaultException异常< RfcServiceFault> rfcEx)
{
// OMG FOR THE幼犬的生命在这里输入
}
赶上(FaultException异常RR )
{
//它总是落在这里
}
赶上(异常前)
{}

我读过,这个类似的问题很多,很多帖子:







  • $问题b $ b


但没有到目前为止似乎帮助,我试图建立WCF在web.config追踪:

 <&System.Diagnostics程序GT; 
<来源和GT;
<信源名称=System.ServiceModel
switchValue =信息,ActivityTracing>
<&听众GT;
<添加名称=日志
型=System.Diagnostics.XmlWriterTraceListener
initializeData =C:\Traces.svclog/>
< /听众>
< /源>
< /来源>
< /system.diagnostics>

和我在那里得到一个svclog文件,我与WCF跟踪查看器中打开,但我只看到了一堆邮件,黄色的显示异常,但它只是证实了客户端已经看到,一个 System.ServiceModel.FaultException 接收,而不是一般的有一个



任何想法如何算出这个?



修改忘了提,我在启用配置我的错误处理程序是这样的:

 < behaviorExtensions> 
.....
<添加名称=faultErrorHandlerBehavior
型=Service.FaultErrorHandler,服务,版本= 1.0.0.0,文化=中立,公钥=空/> ;
.....
< / behaviorExtensions>
< serviceBehaviors>
<行为NAME =ServiceBehavior>
< serviceThrottling maxConcurrentCalls =200maxConcurrentSessions =200
maxConcurrentInstances =200/>
< serviceMetadata httpGetEnabled =真/>
< serviceDebug includeExceptionDetailInFaults =真/>
< faultErrorHandlerBehavior />
< /行为>
< / serviceBehaviors>


解决方案

(这是一个在黑暗中位刺)我相信你可能有一个问题,因为对故障的动作不匹配,预计将在客户端。你能请通过以下方式取代你的CreateMessage:

  =故障Message.CreateMessage(版本,faultMessage,faultException.Action); 


I've read all there is to read on this, but maybe I'm missing something (well, definitely I'm missing something otherwise it would be working already)

I'm throwing some exception error inside my server business layer:

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>();
}

which I leave unhandled in the service, but I have an IErrorHandler to catch and create a 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();
   }
}

No need to ask; I already confirmed with the debugger its entering in the part if (error is RfcException) part, I've stepped through that code and it reach til the end without any trouble.That errorHandler wraps a FaultException<RfcServiceFault> message, the RfcServiceFault message is this

[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; }
}

The service has all the annotations that should have a wcf service with a faultContract:

[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();
}

Now: testing at the client, a simple test like this:

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

I've read, many, many posts about this similar issue:

but nothing so far seems to help, I've tried setting up WCF tracing in the web.config:

<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>

and I get a svclog file in there, I open with WCF Trace viewer, but I only see a bunch of messages, the yellow one show the Exception, but it only confirms what the client is already seeing, a System.ServiceModel.FaultException being received, rather than the generic one

Any ideas how to figure this out?

EDIT forgot to mention, i enabled my error handler in config like this:

<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>
解决方案

(This is a bit of stab in the dark) I believe you may have an issue because the action on the fault does not match that expected at the client. Can you please replace your CreateMessage with the following:

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

这篇关于客户端不会赶上普通的FaultException&LT; T&GT ;,唯一的FaultException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 15:31