2012-01-04 41 views
2

在IIS中但通過工廠運行的Web服務不會保留拋出的原始異常。WCF - 在IIS中運行但通過工廠運行的Web服務不能保持拋出的原始異常

例如:

我的Web服務已經標示了FaultContractAttribute像這樣:

public interface IMyService 
{ 
    [FaultContract(typeof(MyCustomException))] 
    [OperationContract] 
    bool IsAuthorized(); 
} 

我的Web服務實現拋出像這樣一個自定義異常:

public class MyService : IMyService 
{ 
    public bool IsAuthorized() 
    { 
     throw new FaultException<MyCustomException>(fault, fr); 
    } 
} 

Then:

  1. 如果我的WCF - 不使用任何工廠 - 類似於<%@ ServiceHost Language="C#" Debug="true" Service="MyService" %>,然後在客戶端我可以拿起原始異常(MyCustomException)

  2. 如果我的WCF - 使用一些工廠 - 類似於<%@ ServiceHost Language="C#" Debug="true" Service="MyService" Factory="MyFactory" %>,然後在客戶端,我不能沒有用常規跟蹤拿起原始異常(MyCustomException),但只有SOAP異常(FaultException異常)&消息

注:

WCF工廠MyFactory與實現其服務主機包含IErrorHandler

開始在該服務中的行爲服務行爲,方法ProvideFault什麼也不做(我不知道如何通過這種方式來保持原有的除外)

總之,我求求答案從期望:如何在使用一些WCF工廠時保持原始異常(MyCustomException)? 謝謝。

回答

1

在我最近的項目(WCF REST服務),我用WebServiceHostFactory,我仍然能夠做到這一點使用IErrorHandler。查找下面的樣本

我創建了一個類ExceptionInfo,可以序列化併發送回客戶端。

[Serializable] 
public class ExceptionInfo 
{ 
    public string ExceptionType { get; set; } 
    public string ExceptionMessage { get; set; } 
    public string StackTrace { get; set; } 
} 

和實現自定義錯誤處理程序

[DataContract] 
public class MyCustomServiceErrorHandler : IErrorHandler 
{ 
    #region IErrorHandler Members 

    /// <summary> 
    /// This method will execute whenever an exception occurs in WCF method execution 
    /// </summary> 
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     var exceptionInfo = new ExceptionInfo(); 

     if (error is MyCustomException) 
      exceptionInfo.ExceptionType = error.Type.ToString();; 
     else 
      exceptionInfo.Type = "Unhandled Exception"; 

     exceptionInfo.ExceptionMessage = error.Message;    
     exceptionInfo.StackTrace = error.StackTrace; 

     var faultException = new FaultException<ExceptionInfo>(exceptionInfo); 

     object detail = faultException.GetType().GetProperty("Detail").GetGetMethod().Invoke(faultException, null); 

     fault = Message.CreateMessage(version, "", detail, new DataContractSerializer(detail.GetType())); 

     var webBodyFormatMessageProp = new WebBodyFormatMessageProperty(WebContentFormat.Xml); 

     fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProp); 

     var httpResponseMessageProp = new HttpResponseMessageProperty(); 

     httpResponseMessageProp.Headers[HttpResponseHeader.ContentType] = "application/xml"; 
     httpResponseMessageProp.StatusCode = HttpStatusCode.BadRequest; 
     httpResponseMessageProp.StatusDescription = exceptionInfo.ExceptionMessage; 

     fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponseMessageProp); 

    } 

    /// <summary> 
    /// Performs error related behavior 
    /// </summary> 
    /// <param name="error">Exception raised by the program</param> 
    /// <returns></returns> 
    public bool HandleError(Exception error) 
    { 
     // Returning true indicates that an action(behavior) has been taken (in ProvideFault method) on the exception thrown. 
     return true; 
    } 

現在你可以裝飾使用上述處理您的服務。

[ServiceContract]  
[ServiceErrorBehavior(typeof (MyCustomServiceErrorHandler))] 
public class LoginService : ServiceBase 
{} 

在客戶端,則可以檢查響應的HttpStatusCode!= OK和反序列化在消息框中ExceptionInfo類型和顯示的響應或按要求處理。

希望這會有所幫助。

相關問題