FaultFormatter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / FaultFormatter.cs / 3 / FaultFormatter.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic; 
using System.Text;
using System.ServiceModel.Channels; 
using System.ServiceModel.Description; 
using System.Runtime.Serialization;
using System.Xml; 
using System.Reflection;
using System.Diagnostics;

namespace System.ServiceModel.Dispatcher 
{
    class FaultFormatter: IClientFaultFormatter, IDispatchFaultFormatter 
    { 
        FaultContractInfo[] faultContractInfos;
 
        internal FaultFormatter(Type[] detailTypes)
        {
            List faultContractInfoList = new List();
            for (int i = 0; i < detailTypes.Length; i++) 
                faultContractInfoList.Add(new FaultContractInfo(MessageHeaders.WildcardAction, detailTypes[i]));
            AddInfrastructureFaults(faultContractInfoList); 
            faultContractInfos = GetSortedArray(faultContractInfoList); 
        }
 
        internal FaultFormatter(SynchronizedCollection faultContractInfoCollection)
        {
            List faultContractInfoList;
            lock (faultContractInfoCollection.SyncRoot) 
            {
                faultContractInfoList = new List(faultContractInfoCollection); 
            } 
            AddInfrastructureFaults(faultContractInfoList);
            this.faultContractInfos = GetSortedArray(faultContractInfoList); 
        }

        public MessageFault Serialize(FaultException faultException, out string action)
        { 
            XmlObjectSerializer serializer = null;
            Type detailType = null; 
            string faultExceptionAction = action = faultException.Action; 

            Type faultExceptionOfT = null; 
            for (Type faultType = faultException.GetType(); faultType != typeof(FaultException); faultType = faultType.BaseType)
            {
                if (faultType.IsGenericType && (faultType.GetGenericTypeDefinition() == typeof(FaultException<>)))
                { 
                    faultExceptionOfT = faultType;
                    break; 
                } 
            }
            if (faultExceptionOfT != null) 
            {
                detailType = faultExceptionOfT.GetGenericArguments()[0];
                serializer = GetSerializer(detailType, faultExceptionAction, out action);
            } 
            return CreateMessageFault(serializer, faultException, detailType);
        } 
 
        public FaultException Deserialize(MessageFault messageFault, string action)
        { 
            if (!messageFault.HasDetail)
                return new FaultException(messageFault, action);

            return CreateFaultException(messageFault, action); 
        }
 
        protected virtual XmlObjectSerializer GetSerializer(Type detailType, string faultExceptionAction, out string action) 
        {
            action = faultExceptionAction; 
            FaultContractInfo faultInfo = null;
            for (int i = 0; i < faultContractInfos.Length; i++)
            {
                if (faultContractInfos[i].Detail == detailType) 
                {
                    faultInfo = faultContractInfos[i]; 
                    break; 
                }
            } 
            if (faultInfo != null)
            {
                if (action == null)
                    action = faultInfo.Action; 

                return faultInfo.Serializer; 
            } 
            else
                return DataContractSerializerDefaults.CreateSerializer(detailType, int.MaxValue /* maxItemsInObjectGraph */ ); 
        }

        protected virtual FaultException CreateFaultException(MessageFault messageFault, string action)
        { 
            IList faultInfos;
            if (action != null) 
            { 
                faultInfos = new List();
                for (int i = 0; i < faultContractInfos.Length; i++) 
                {
                    if (faultContractInfos[i].Action == action || faultContractInfos[i].Action == MessageHeaders.WildcardAction)
                    {
                        faultInfos.Add(faultContractInfos[i]); 
                    }
                } 
            } 
            else
            { 
                faultInfos = faultContractInfos;
            }

            Type detailType = null; 
            object detailObj = null;
            for (int i = 0; i < faultInfos.Count; i++) 
            { 
                FaultContractInfo faultInfo = faultInfos[i];
                XmlDictionaryReader detailReader = messageFault.GetReaderAtDetailContents(); 
                XmlObjectSerializer serializer = faultInfo.Serializer;
                if (serializer.IsStartObject(detailReader))
                {
                    detailType = faultInfo.Detail; 
                    try
                    { 
                        detailObj = serializer.ReadObject(detailReader); 
                        FaultException faultException = CreateFaultException(messageFault, action,
                            detailObj, detailType, detailReader); 
                        if (faultException != null)
                            return faultException;
                    }
                    catch (SerializationException) 
                    {
                    } 
                } 
            }
            return new FaultException(messageFault, action); 
        }

        protected FaultException CreateFaultException(MessageFault messageFault, string action,
            object detailObj, Type detailType, XmlDictionaryReader detailReader) 
        {
            if (!detailReader.EOF) 
            { 
                detailReader.MoveToContent();
                if (detailReader.NodeType != XmlNodeType.EndElement && !detailReader.EOF) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ExtraContentIsPresentInFaultDetail)));
            }
            bool isDetailObjectValid = true;
            if (detailObj == null) 
            {
                isDetailObjectValid = !detailType.IsValueType; 
            } 
            else
            { 
                isDetailObjectValid = detailType.IsAssignableFrom(detailObj.GetType());
            }
            if (isDetailObjectValid)
            { 
                Type knownFaultType = typeof(FaultException<>).MakeGenericType(detailType);
                return (FaultException)Activator.CreateInstance(knownFaultType, 
                                                            detailObj, 
                                                            messageFault.Reason,
                                                            messageFault.Code, 
                                                            action);
            }
            return null;
        } 

        static FaultContractInfo[] GetSortedArray(List faultContractInfoList) 
        { 
            FaultContractInfo[] temp = faultContractInfoList.ToArray();
            Array.Sort(temp, 
                delegate(FaultContractInfo x, FaultContractInfo y)
                { return string.CompareOrdinal(x.Action, y.Action); }
                );
            return temp; 
        }
 
        static void AddInfrastructureFaults(List faultContractInfos) 
        {
            faultContractInfos.Add(new FaultContractInfo(FaultCodeConstants.Actions.NetDispatcher, typeof(ExceptionDetail))); 
        }

        static MessageFault CreateMessageFault(XmlObjectSerializer serializer, FaultException faultException, Type detailType)
        { 
            if (detailType == null)
            { 
                if (faultException.Fault != null) 
                    return faultException.Fault;
                return MessageFault.CreateFault(faultException.Code, faultException.Reason); 
            }
            Debug.Assert(serializer != null);

            Type operationFaultType = typeof(OperationFault<>).MakeGenericType(detailType); 
            return (MessageFault)Activator.CreateInstance(operationFaultType, serializer, faultException);
        } 
 
        internal class OperationFault : XmlObjectSerializerFault
        { 
            public OperationFault(XmlObjectSerializer serializer, FaultException faultException):
                base(faultException.Code, faultException.Reason,
                     faultException.Detail,
                     serializer, 
                     string.Empty/*actor*/,
                     string.Empty/*node*/) 
            { 
            }
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK