Не повезло с тем, чтобы заставить его работать через файлы конфигурации, поэтому решил попробовать более надежный способ его настройки с помощью атрибутов уровня класса. Если я смогу заставить это работать, это, несомненно, отличный способ обернуть исключения в Сбойах на уровне сервиса без трепетания большого количества кода.
Однако код в атрибуте, кажется, никогда не запускается - несмотря на код, который определяет, что атрибут отлично компилируется и распознается в IDE. У меня закончились вещи для решения этой проблемы - исключение, которое нужно обработать, и его просто выбросили.
Я также позаимствовал и вырубил фрагмент кода, найденный на CodePlex, который находится на сайте rorys, чтобы упростить его для решения этой проблемы без изменения его функции (устранены избыточные перегрузки)
это сводит меня с ума ... пожалуйста, помогите! : D
Первоцвет Рори - реализация атрибута
Первоцвет Рори - 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;
}
}