XmlSerializerOperationGenerator.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 / Description / XmlSerializerOperationGenerator.cs / 1 / XmlSerializerOperationGenerator.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

using System.Collections.Generic; 
using System.ServiceModel.Channels;
using System.ServiceModel; 
using System.ServiceModel.Dispatcher; 
using System.CodeDom;
using System.Globalization; 
using System.Text;
using System.Xml.Serialization;
using System.CodeDom.Compiler;
using System.Runtime.Serialization; 

namespace System.ServiceModel.Description 
{ 
    class XmlSerializerOperationGenerator : IOperationBehavior, IOperationContractGenerationExtension
    { 
        OperationGenerator operationGenerator;
        Dictionary partInfoTable;
        Dictionary operationAttributes = new Dictionary();
        XmlCodeExporter xmlExporter; 
        SoapCodeExporter soapExporter;
 
        XmlSerializerImportOptions options; 
        CodeNamespace codeNamespace;
 
        internal XmlSerializerOperationGenerator(XmlSerializerImportOptions options)
        {
            operationGenerator = new OperationGenerator();
            this.options = options; 
            this.codeNamespace = GetTargetCodeNamespace(options);
            partInfoTable = new Dictionary(); 
        } 

        static CodeNamespace GetTargetCodeNamespace(XmlSerializerImportOptions options) 
        {
            CodeNamespace targetCodeNamespace = null;
            string clrNamespace = options.ClrNamespace ?? string.Empty;
            foreach (CodeNamespace ns in options.CodeCompileUnit.Namespaces) 
            {
                if (ns.Name == clrNamespace) 
                { 
                    targetCodeNamespace = ns;
                } 
            }
            if (targetCodeNamespace == null)
            {
                targetCodeNamespace = new CodeNamespace(clrNamespace); 
                options.CodeCompileUnit.Namespaces.Add(targetCodeNamespace);
            } 
            return targetCodeNamespace; 
        }
 
        internal void Add(MessagePartDescription part, XmlMemberMapping memberMapping, XmlMembersMapping membersMapping, bool isEncoded)
        {
            PartInfo partInfo = new PartInfo();
            partInfo.MemberMapping = memberMapping; 
            partInfo.MembersMapping = membersMapping;
            partInfo.IsEncoded = isEncoded; 
            partInfoTable[part] = partInfo; 
        }
 
        public XmlCodeExporter XmlExporter
        {
            get
            { 
                if (this.xmlExporter == null)
                { 
                    this.xmlExporter = new XmlCodeExporter(this.codeNamespace, this.options.CodeCompileUnit, this.options.CodeProvider, 
                        this.options.WebReferenceOptions.CodeGenerationOptions, null);
                } 
                return xmlExporter;
            }
        }
 
        public SoapCodeExporter SoapExporter
        { 
            get 
            {
                if (this.soapExporter == null) 
                {
                    this.soapExporter = new SoapCodeExporter(this.codeNamespace, this.options.CodeCompileUnit, this.options.CodeProvider,
                        this.options.WebReferenceOptions.CodeGenerationOptions, null);
                } 
                return soapExporter;
            } 
        } 

        OperationGenerator OperationGenerator 
        {
            get { return this.operationGenerator; }
        }
 
        internal Dictionary OperationAttributes
        { 
            get { return operationAttributes; } 
        }
 

        void IOperationBehavior.Validate(OperationDescription description)
        {
        } 

        void IOperationBehavior.AddBindingParameters(OperationDescription description, BindingParameterCollection parameters) 
        { 
        }
 
        void IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch) { }

        void IOperationBehavior.ApplyClientBehavior(OperationDescription description, ClientOperation proxy) { }
 
        static object contractMarker = new object();
        // Assumption: gets called exactly once per operation 
        void IOperationContractGenerationExtension.GenerateOperation(OperationContractGenerationContext context) 
        {
            if (context == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            if (partInfoTable != null && partInfoTable.Count > 0)
            {
                Dictionary alreadyExported = new Dictionary(); 
                foreach (MessageDescription message in context.Operation.Messages)
                { 
                    foreach (MessageHeaderDescription header in message.Headers) 
                        GeneratePartType(alreadyExported, header);
                    if (OperationFormatter.IsValidReturnValue(message.Body.ReturnValue)) 
                        GeneratePartType(alreadyExported, message.Body.ReturnValue);

                    foreach (MessagePartDescription part in message.Body.Parts)
                        GeneratePartType(alreadyExported, part); 
                }
            } 
            XmlSerializerOperationBehavior xmlSerializerOperationBehavior = context.Operation.Behaviors.Find() as XmlSerializerOperationBehavior; 
            if (xmlSerializerOperationBehavior == null)
                return; 

            XmlSerializerFormatAttribute xmlSerializerFormatAttribute = (xmlSerializerOperationBehavior == null)? new XmlSerializerFormatAttribute() : xmlSerializerOperationBehavior.XmlSerializerFormatAttribute;
            OperationFormatStyle style = xmlSerializerFormatAttribute.Style;
            operationGenerator.GenerateOperation(context, ref style, xmlSerializerFormatAttribute.IsEncoded, new WrappedBodyTypeGenerator(context), new Dictionary>()); 
            context.ServiceContractGenerator.AddReferencedAssembly(typeof(System.Xml.Serialization.XmlTypeAttribute).Assembly);
            xmlSerializerFormatAttribute.Style = style; 
            context.SyncMethod.CustomAttributes.Add(OperationGenerator.GenerateAttributeDeclaration(context.Contract.ServiceContractGenerator, xmlSerializerFormatAttribute)); 
            AddKnownTypes(context.SyncMethod.CustomAttributes, xmlSerializerFormatAttribute.IsEncoded ? SoapExporter.IncludeMetadata : XmlExporter.IncludeMetadata);
            DataContractSerializerOperationGenerator.UpdateTargetCompileUnit(context, this.options.CodeCompileUnit); 
        }

        private void AddKnownTypes(CodeAttributeDeclarationCollection destination, CodeAttributeDeclarationCollection source)
        { 
            foreach (CodeAttributeDeclaration attribute in source)
            { 
                CodeAttributeDeclaration knownType = ToKnownType(attribute); 
                if (knownType != null)
                { 
                    destination.Add(knownType);
                }
            }
        } 

        // Convert [XmlInclude] or [SoapInclude] attribute to [KnownType] attribute 
        private CodeAttributeDeclaration ToKnownType(CodeAttributeDeclaration include) 
        {
            if (include.Name == typeof(SoapIncludeAttribute).FullName || include.Name == typeof(XmlIncludeAttribute).FullName) 
            {
                CodeAttributeDeclaration knownType = new CodeAttributeDeclaration(new CodeTypeReference(typeof(ServiceKnownTypeAttribute)));
                foreach (CodeAttributeArgument argument in include.Arguments)
                { 
                    knownType.Arguments.Add(argument);
                } 
                return knownType; 
            }
            return null; 
        }

        private void GeneratePartType(Dictionary alreadyExported, MessagePartDescription part)
        { 
            if (!partInfoTable.ContainsKey(part))
                return; 
            PartInfo partInfo = partInfoTable[part]; 
            XmlMembersMapping membersMapping = partInfo.MembersMapping;
            XmlMemberMapping memberMapping = partInfo.MemberMapping; 
            if (!alreadyExported.ContainsKey(membersMapping))
            {
                if (partInfo.IsEncoded)
                    SoapExporter.ExportMembersMapping(membersMapping); 
                else
                    XmlExporter.ExportMembersMapping(membersMapping); 
                alreadyExported.Add(membersMapping, membersMapping); 
            }
            CodeAttributeDeclarationCollection additionalAttributes = new CodeAttributeDeclarationCollection(); 
            if (partInfo.IsEncoded)
                SoapExporter.AddMappingMetadata(additionalAttributes, memberMapping, false/*forceUseMemberName*/);
            else
                XmlExporter.AddMappingMetadata(additionalAttributes, memberMapping, part.Namespace, false/*forceUseMemberName*/); 
            part.BaseType = GetTypeName (memberMapping);
            operationGenerator.ParameterTypes.Add(part, new CodeTypeReference(part.BaseType)); 
            operationGenerator.ParameterAttributes.Add(part, additionalAttributes); 
        }
 
        internal string GetTypeName(XmlMemberMapping member)
        {
            string typeName = member.GenerateTypeName(options.CodeProvider);
            if (codeNamespace != null && !string.IsNullOrEmpty(codeNamespace.Name)) 
            {
                foreach(CodeTypeDeclaration typeDecl in codeNamespace.Types) 
                { 
                    if (typeDecl.Name == typeName)
                    { 
                        typeName = codeNamespace.Name + "." + typeName;
                    }
                }
            } 
            return typeName;
        } 
 
        class PartInfo
        { 
            internal XmlMemberMapping MemberMapping;
            internal XmlMembersMapping MembersMapping;
            internal bool IsEncoded;
        } 

        internal class WrappedBodyTypeGenerator : IWrappedBodyTypeGenerator 
        { 
            OperationContractGenerationContext context;
            public WrappedBodyTypeGenerator(OperationContractGenerationContext context) 
            {
                this.context = context;
            }
            public void ValidateForParameterMode(OperationDescription operation) 
            {
            } 
 
            public void AddMemberAttributes(XmlName messageName, MessagePartDescription part, CodeAttributeDeclarationCollection importedAttributes, CodeAttributeDeclarationCollection typeAttributes, CodeAttributeDeclarationCollection fieldAttributes)
            { 
                if (importedAttributes != null)
                    fieldAttributes.AddRange(importedAttributes);
            }
            public void AddTypeAttributes(string messageName, string typeNS, CodeAttributeDeclarationCollection typeAttributes, bool isEncoded) 
            {
                // we do not need top-level attibutes for the encoded SOAP 
                if (isEncoded) 
                    return;
                XmlTypeAttribute xmlType = new XmlTypeAttribute(); 
                xmlType.Namespace = typeNS;
                typeAttributes.Add(OperationGenerator.GenerateAttributeDeclaration(context.Contract.ServiceContractGenerator, xmlType));
            }
        } 
    }
} 

// 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