2010-07-05 3 views
2

Не повезло с тем, что он работал через файлы конфигурации, поэтому решил попытаться найти более надежный маршрут doign через атрибуты уровня класса. Если я смогу получить эту работу, это, безусловно, отличный способ обернуть исключениями в Faults на уровне обслуживания, если вы будете перемещать много кода.Внедрение IErrorHandler с использованием уровня класса Атрибуты в WCF

Однако код в атрибуте никогда не запускается - несмотря на код, который отлично описывает атрибут и распознается 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 на компьютере, на котором работает w w. Не должно быть необходимости в изменении веб-конфигурации, поскольку этот метод реализации должен быть полностью независимым. Хостинг - это IIS на Windows 7, и ни одна из точек останова вне основного контракта не может быть удалена - они были на каждой записи метода. Ничего не прослеживалось ... как будто код не был там после компиляции - тэг атрибута не вызвал никаких исключений и был счастлив. В любом случае, ваш код, который я опубликовал из вашего блога, так что я думаю, что ответ за вами. Большое спасибо за сообщения в блоге. –

+0

Я рад, что это сработало для вас :) Я нахожу, что мне нужно войти в вызов прокси-сервера клиента WCF, чтобы иметь возможность ударить точки останова в размещенной службе. Возможно, это проблема, с которой вы столкнулись, если вы перешагиваете вызов WCF или запускаете без клиентских точек останова. –

+0

Я был напуган с точки останова и вступил на службу ... это действительно было чудом. Я переустановил свою машину, и она работала отлично в первый раз. –

 Смежные вопросы

  • Нет связанных вопросов^_^