2010-07-05 57 views
2

通過配置文件無法運行它,所以決定嘗試去通過類級別屬性進行更合理的doign操作。如果我可以得到這個工作,那麼顯然是一種很好的方法,可以在處理服務層的故障時將異常封裝在許多代碼中。在WCF中使用類級別屬性實現IErrorHandler

但是,屬性中的代碼似乎永遠不會運行 - 儘管代碼定義了屬性編譯非常好,並被IDE識別。關於解決這個問題,我已經耗盡了一些東西 - 只是被處理的異常而被拋出。

我也借用和砍下的一段代碼在CodePlex上發現,是rorys網站簡化它對於這個問題,而不改變其功能(除去多餘的過載)

這是推動我瘋了...請幫忙! :d

Rory Primrose - attribute implementation

Rory Primrose - IErrorHandlerImplementation

的代碼:

服務接口和實現

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    [FaultContract(typeof(FaultException))] 
    string GetData(int value); 
} 

[ErrorHandler(typeof(KnownErrorHandler))] 
public class Service1 : IService1 
{ 
    public string GetData(int value) 
    { 
     throw new Exception("This exception should get handled."); 
    } 
} 

KnownErrorHandler實現:

public class KnownErrorHandler : IErrorHandler 
{ 
    public bool HandleError(Exception error) 
    { 
     Trace.WriteLine(error.ToString()); 
     return true; 
    } 

    public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault) 
    { 
     FaultException faultException = new FaultException("Server error encountered. All details have been logged."); 
     MessageFault messageFault = faultException.CreateMessageFault(); 
     fault = Message.CreateMessage(version, messageFault, faultException.Action); 
    } 
} 

屬性定義 - 懷疑問題在這裏。我相當確定這是我如何使用這段代碼。

[AttributeUsage(AttributeTargets.Class)] 
    public sealed class ErrorHandler : Attribute, IServiceBehavior 
    { 
     public ErrorHandler(Type errorHandler) 
     { 
      if (errorHandler == null) 
      {throw new ArgumentNullException("errorHandler");} 
      Type[] errorHandlerTypes = new[] { errorHandler }; 
      Initialize(errorHandlerTypes); 
     } 

     public void AddBindingParameters(
      ServiceDescription serviceDescription, 
      ServiceHostBase serviceHostBase, 
      Collection<ServiceEndpoint> endpoints, 
      BindingParameterCollection bindingParameters) 
     { 
      // Nothing to do here 
     } 

     public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
     { 
      if (serviceHostBase == null) 
      { 
       throw new ArgumentNullException("serviceHostBase"); 
      } 

      // Loop through each channel dispatcher 
      for (Int32 dispatcherIndex = 0; dispatcherIndex < serviceHostBase.ChannelDispatchers.Count; dispatcherIndex++) 
      { 
       // Get the dispatcher for this index and cast to the type we are after 
       ChannelDispatcher dispatcher = (ChannelDispatcher)serviceHostBase.ChannelDispatchers[dispatcherIndex]; 

       // Loop through each error handler 
       for (Int32 typeIndex = 0; typeIndex < ErrorHandlerTypes.Count; typeIndex++) 
       { 
        Type errorHandlerType = ErrorHandlerTypes[typeIndex]; 

        // Create a new error handler instance 
        IErrorHandler handler = (IErrorHandler)Activator.CreateInstance(errorHandlerType); 

        // Add the handler to the dispatcher 
        dispatcher.ErrorHandlers.Add(handler); 
       } 
      } 
     } 

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


     private void Initialize(Type[] errorHandlerTypes) 
     { 
      const String ErrorHandlerTypesParameterName = "errorHandlerTypes"; 

      if (errorHandlerTypes == null) 
      { 
       throw new ArgumentNullException(ErrorHandlerTypesParameterName); 
      } 

      if (errorHandlerTypes.Length == 0) 
      { 
       throw new ArgumentOutOfRangeException(ErrorHandlerTypesParameterName); 
      } 

      List<String> typeNames = new List<String>(errorHandlerTypes.Length); 

      // Loop through each item supplied 
      for (Int32 index = 0; index < errorHandlerTypes.Length; index++) 
      { 
       Type errorHandlerType = errorHandlerTypes[index]; 

       // Check if the item supplied is null 
       if (errorHandlerType == null) 
       { 
        throw new ArgumentNullException(ErrorHandlerTypesParameterName); 
       } 

       // Check if the type doesn't define the IErrorHandler interface 
       if (typeof(IErrorHandler).IsAssignableFrom(errorHandlerType) == false) 
       { 
        // We can't use this type 
        throw new InvalidCastException(); 
       } 

       String assemblyQualifiedName = errorHandlerType.AssemblyQualifiedName; 

       if (typeNames.Contains(assemblyQualifiedName) == false) 
       { 
        typeNames.Add(assemblyQualifiedName); 
       } 
       else 
       { 
        throw new ArgumentException(
         String.Format(CultureInfo.CurrentCulture, "Duplicate ErrorType Provided", assemblyQualifiedName)); 
       } 
      } 

      // Store the types 
      ErrorHandlerTypes = new ReadOnlyCollection<Type>(errorHandlerTypes); 
     } 

     /// <summary> 
     /// Gets the error handler types. 
     /// </summary> 
     /// <value> 
     /// The error handler types. 
     /// </value> 
     public ReadOnlyCollection<Type> ErrorHandlerTypes 
     { 
      get; 
      private set; 
     } 
    } 

回答

0

很難在這裏幫助你,因爲你沒有提供任何有關你的應用程序發生了什麼的信息。

  • 爲什麼它不起作用?
  • 發生了什麼(預期與實際行爲/結果)?
  • 你的客戶有什麼例外嗎?
  • 你有追蹤設置嗎?
  • 事件日誌中是否有任何東西
  • 什麼是您的WCF託管方案(winforms,windows服務,IIS,casini)?
  • 你把錯誤處理程序中的斷點?
  • 你的代碼是什麼樣的?
  • 你的配置是什麼樣的?
+0

原來的代碼工作正常... iis在我工作的計算機上壞了。應該不需要修改網絡配置,因爲這種實現方法應該是完全獨立的。 主機是Windows 7上的IIS,並且主要合約調用之外的斷點都不會被打 - 它們在每個方法條目上。沒有什麼被追查出來......就好像編譯後的代碼不存在 - 屬性標記沒有引起異常並且很高興。 無論如何,你的代碼,我從你的博客發佈,所以我想答案是你的。非常感謝博客文章。 – 2010-07-13 10:36:40

+0

我很高興它爲你工作:) 我發現我需要步入一個WCF客戶端代理呼叫,以便能夠擊中託管服務內的斷點。如果您正在跨過WCF調用或運行沒有客戶端斷點的運行,那麼可能是您遇到的問題。 – 2010-07-14 04:32:24

+0

我與斷點奔跑,並正在進入服務......它真的是二戰變得更加奇怪。我重新安裝了我的機器,它第一次完美運行。 – 2010-07-22 13:48:07

相關問題