2011-07-05 12 views
14

Tüm bunları okumak için okuduğumu okudum, ama belki bir şeyleri özlüyorum (iyi, kesinlikle bir şey eksiktir, aksi halde çalışıyor olabilir)istemcisi, yalnızca FaultException < T > genel hatalarını yakalamayacaktır, sadece FaultException

benim sunucu iş tabakasının içindeki bazı istisna hatası atıyorum: Ben hizmetinde işlenmeyen bırakın, ancak bir IErrorHandler var

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

yakalamak ve yaratmak için bir 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(); 
    } 
} 

Sormaya gerek yoktur; Ben zaten hata ayıklayıcı ile bölüm if (error is RfcException) bölümü girerek onayladı, ben bu kodu adım attı ve sonuna kadar herhangi bir sorun olmadan ulaşır. Şimdi

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

: errorHandler bir FaultException<RfcServiceFault> mesaj sarar , RfcServiceFault mesaj servisi bir faultContract ile wcf hizmeti olması gereken tüm açıklamaları vardır bu

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

olan en test İstemci, bu gibi basit bir test:

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

Çok okudum, Bu benzer konuda birçok mesaj:

ama hiçbir şey şimdiye kadar, ben de izleme WCF kurma denedim yardımcı olacak gibi görünüyor 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> 

ve orada bir svclog dosyası alıyorum, WCF Trace görüntüleyicisiyle açıyorum, ancak yalnızca bir grup iletiyi görüyorum, sarı olanı Özel Durum'u gösteriyor, ancak yalnızca istemcinin ne gördüğünü doğrulayan bir System.ServiceModel.FaultException alınıyor jenerik bir yerine,

Bunu nasıl anlayacağınıza dair herhangi bir fikriniz var mı?

DÜZENLEME ben böyle config benim hata işleyicisi etkin, söylemeyi unutmuşum:

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

i Bir seferde çok fazla sorunları çözmek için çalışıyoruz – lurscher

+3

hizmet faydan sözlük özelliği yorumlama deneyecektir. IErrorHandler'ınızı kaldırabilir ve dize dışında ek özellikler olmadan yeni bir CustomFault kullanabilir misiniz?Sözlük doesnt çıkarmadan –

+0

@Henk, ben sadece dize DataMembers başbaşa kaldım Sözlük özelliğini yorum yaptıktan sonra, durumun – lurscher

cevap

14

(Bu karanlıkta stab biraz) Sana bir sorun olabilir inanıyoruz eylem üzerinde çünkü Arıza, istemcide beklenen eşleşmiyor. Aşağıdaki ile CreateMessage değiştirin misiniz:

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

sirkte nasıl yalıtılacağına dair herhangi bir bilgi vermemişti. gücü hisset, WCF Jedi'sin! .. OWK'nin dediği gibi, "Gözlerin seni aldatabilir, onlara güvenme." – lurscher

+0

teşekkürler lurscher. Sorunu duyduğunu duyduğuma sevindim. Bu yazı için –

+1

thx, bu sorunu giderdim, bu arada, bildirimde bulunmanız gerekir: eklediğinizde ** [FaultContract (typeof (RfcServiceFault))] ** Nitelik, ** Yeniden kullanım ** Servis on istemci Yan – Gavin