Vývoj moderních aplikací na platformě Microsoft .NET

Je vyžadována podpora jazyka JavaScript

Některé stránky na tomto webu vyžadují podporu jazyka JavaScript. Váš webový prohlížeč jazyk JavaScript nepodporuje nebo jazyk JavaScript není povolen.

Chcete-li zjistit, zda webový prohlížeč podporuje jazyk JavaScript nebo jazyk JavaScript chcete povolit, přečtěte si nápovědu k vašemu webovému prohlížeči.


ErrorHandler.cs

Download file

Toto je zdrojový kód souboru ErrorHandler.cs

ErrorHandlingBehavior Attribute for Silverlight WCF services error handling.

using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace IMP.Shared
{
    internal sealed class ErrorHandler : IErrorHandler
    {
        #region member varible and default property initialization
        private ErrorHandlingBehaviorAttribute _attribute;
        private IExceptionToFaultConverter _converter;
        #endregion

        #region constructors and destructors
        public ErrorHandler(ErrorHandlingBehaviorAttribute attribute)
        {
            _attribute = attribute;
            if (_attribute.ExceptionToFaultConverter != null)
                _converter = (IExceptionToFaultConverter)Activator.CreateInstance(_attribute.ExceptionToFaultConverter);
        }
        #endregion

        #region IErrorHandler Members
        public bool HandleError(Exception error)
        {
            return true;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            //If it's a FaultException already, then we have nothing to do
            if (error is FaultException)
            {
                return;
            }

            ServiceEndpoint endpoint =
                OperationContext.Current.Host.Description.Endpoints.Find(
                    OperationContext.Current.EndpointDispatcher.EndpointAddress.Uri);
            DispatchOperation dispatchOperation =
                OperationContext.Current.EndpointDispatcher.DispatchRuntime.Operations.Where(
                    op => op.Action == OperationContext.Current.IncomingMessageHeaders.Action).First();
            OperationDescription operationDesc =
                endpoint.Contract.Operations.Find(dispatchOperation.Name);

            object faultDetail = GetFaultDetail(operationDesc.SyncMethod, operationDesc.Faults, error);
            if (faultDetail != null)
            {
                Type faultExceptionType =
                    typeof(FaultException<>).MakeGenericType(faultDetail.GetType());
                FaultException faultException =
                    (FaultException)Activator.CreateInstance(faultExceptionType, faultDetail, error.Message);
                MessageFault faultMessage = faultException.CreateMessageFault();
                fault = Message.CreateMessage(version, faultMessage, faultException.Action);
            }
        }
        #endregion

        #region private member functions
        private object GetFaultDetail(MethodInfo method, FaultDescriptionCollection faults, Exception error)
        {
            Type exceptionType = error.GetType();
            object faultDetail = null;

            if (_converter != null)
            {
                faultDetail = _converter.ConvertExceptionToFaultDetail(error);
                if (faultDetail != null)
                {
                    return faultDetail;
                }
            }

            if (method != null)
            {
                foreach (FaultDescription faultDesc in faults)
                {
                    var constructor = faultDesc.DetailType.GetConstructor(BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Instance, null, new Type[] { exceptionType }, null);
                    if (constructor != null)
                    {
                        return constructor.Invoke(new object[] { error });
                    }
                }
            }

            foreach (FaultDescription faultDesc in faults)
            {
                if (faultDesc.DetailType == exceptionType)
                {
                    return error;
                }
            }

            return null;
        }
        #endregion
    }

    [AttributeUsage(AttributeTargets.Class)]
    internal sealed class ErrorHandlingBehaviorAttribute : Attribute, IServiceBehavior
    {
        #region member varible and default property initialization
        private Type _exceptionToFaultConverterType;
        #endregion

        #region property getters/setters
        public Type ExceptionToFaultConverter
        {
            get
            {
                return _exceptionToFaultConverterType;
            }
            set
            {
                if (!typeof(IExceptionToFaultConverter).IsAssignableFrom(value))
                    throw new ArgumentException("Fault converter doesn't implement IExceptionToFaultConverter.", "value");
                _exceptionToFaultConverterType = value;
            }
        }
        #endregion

        #region IServiceBehavior Members
        public void AddBindingParameters(ServiceDescription serviceDescription,
            ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters) { }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase chanDispBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = chanDispBase as ChannelDispatcher;
                if (channelDispatcher == null)
                    continue;
                channelDispatcher.ErrorHandlers.Add(new ErrorHandler(this));
            }
        }

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

    internal interface IExceptionToFaultConverter
    {
        object ConvertExceptionToFaultDetail(Exception error);
    }
}