WebMethodAttribute.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / WebMethodAttribute.cs / 1305376 / WebMethodAttribute.cs

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

namespace System.Web.Services { 
 
    using System;
    using System.Reflection; 
    using System.Collections;
    using System.Web.Util;
    using System.Web.Services.Protocols;
    using System.Xml.Serialization; 
    using System.EnterpriseServices;
    using System.Text; 
    using System.Runtime.InteropServices; 

    ///  
    /// 
    ///     The WebMethod attribute must be placed on a method in a Web Service class to mark it as available
    ///       to be called via the Web. The method and class must be marked public and must run inside of
    ///       an ASP.NET Web application. 
    /// 
    [AttributeUsage(AttributeTargets.Method)] 
    public sealed class WebMethodAttribute : Attribute { 
        private int transactionOption; // this is an int to prevent system.enterpriseservices.dll from getting loaded
        private bool enableSession; 
        private int cacheDuration;
        private bool bufferResponse;
        private string description;
        private string messageName; 

        private bool transactionOptionSpecified; 
        private bool enableSessionSpecified; 
        private bool cacheDurationSpecified;
        private bool bufferResponseSpecified; 
        private bool descriptionSpecified;
        private bool messageNameSpecified;

        ///  
        /// 
        /// Initializes a new instance of the  
        /// class. 
        /// 
        public WebMethodAttribute() { 
            enableSession = false;
            transactionOption = 0; // TransactionOption.Disabled
            cacheDuration = 0;
            bufferResponse = true; 
        }
 
        ///  
        /// 
        /// Initializes a new instance of the  
        /// class.
        /// 
        public WebMethodAttribute(bool enableSession)
            : this() { 
            EnableSession = enableSession;
        } 
 
        /// 
        ///  
        /// Initializes a new instance of the 
        /// class.
        /// 
        public WebMethodAttribute(bool enableSession, TransactionOption transactionOption) 
            : this() {
            EnableSession = enableSession; 
            this.transactionOption = (int)transactionOption; 
            transactionOptionSpecified = true;
        } 

        /// 
        /// 
        /// Initializes a new instance of the  
        /// class.
        ///  
        public WebMethodAttribute(bool enableSession, TransactionOption transactionOption, int cacheDuration) { 
            EnableSession = enableSession;
            this.transactionOption = (int)transactionOption; 
            transactionOptionSpecified = true;
            CacheDuration = cacheDuration;
            BufferResponse = true;
        } 

        ///  
        ///  
        /// Initializes a new instance of the 
        /// class. 
        /// 
        public WebMethodAttribute(bool enableSession, TransactionOption transactionOption, int cacheDuration, bool bufferResponse) {
            EnableSession = enableSession;
            this.transactionOption = (int)transactionOption; 
            transactionOptionSpecified = true;
            CacheDuration = cacheDuration; 
            BufferResponse = bufferResponse; 
        }
 
        /// 
        /// 
        ///     A message that describes the Web service method.
        ///       The message is used in description files generated for a Web Service, such as the Service Contract and the Service Description page. 
        /// 
        public string Description { 
            get { 
                return (description == null) ? string.Empty : description;
            } 

            set {
                description = value;
                descriptionSpecified = true; 
            }
        } 
        internal bool DescriptionSpecified { get { return descriptionSpecified; } } 

        ///  
        /// 
        ///    Indicates wheter session state is enabled for a Web service Method. The default is false.
        /// 
        public bool EnableSession { 
            get {
                return enableSession; 
            } 

            set { 
                enableSession = value;
                enableSessionSpecified = true;
            }
        } 
        internal bool EnableSessionSpecified { get { return enableSessionSpecified; } }
 
        ///  
        /// 
        ///    Indicates the number of seconds the response should be cached. Defaults to 0 (no caching). 
        ///          Should be used with caution when requests are likely to be very large.
        /// 
        public int CacheDuration {
            get { 
                return cacheDuration;
            } 
 
            set {
                cacheDuration = value; 
                cacheDurationSpecified = true;
            }
        }
        internal bool CacheDurationSpecified { get { return cacheDurationSpecified; } } 

        ///  
        ///  
        ///    Indicates whether the response for this request should be buffered. Defaults to false.
        ///  
        public bool BufferResponse {
            get {
                return bufferResponse;
            } 

            set { 
                bufferResponse = value; 
                bufferResponseSpecified = true;
            } 
        }
        internal bool BufferResponseSpecified { get { return bufferResponseSpecified; } }

        ///  
        /// 
        ///     
        ///       Indicates the transaction participation mode of a Web Service Method.  
        /// 
        public TransactionOption TransactionOption { 
            get {
                return (TransactionOption)transactionOption;
            }
            set { 
                transactionOption = (int)value;
                transactionOptionSpecified = true; 
            } 
        }
        internal bool TransactionOptionSpecified { get { return transactionOptionSpecified; } } 

        internal bool TransactionEnabled {
            get {
                return transactionOption != 0; 
            }
        } 
 
        /// 
        ///  
        ///    The name used for the request and response message containing the
        ///    data passed to and returned from this method.
        /// 
        public string MessageName { 
            get {
                return messageName == null ? string.Empty : messageName; 
            } 

            set { 
                messageName = value;
                messageNameSpecified = true;
            }
        } 
        internal bool MessageNameSpecified { get { return messageNameSpecified; } }
    } 
 
    internal class WebMethodReflector {
        private WebMethodReflector() {} 
        /*
        internal static WebMethodAttribute GetAttribute(MethodInfo implementation) {
            return GetAttribute(implementation, null);
        } 
        */
 
        internal static WebMethodAttribute GetAttribute(MethodInfo implementation, MethodInfo declaration) { 
            WebMethodAttribute declAttribute = null;
            WebMethodAttribute implAttribute = null; 
            object[] attrs;

            if (declaration != null) {
                attrs = declaration.GetCustomAttributes(typeof(WebMethodAttribute), false); 
                if (attrs.Length > 0) {
                    declAttribute = (WebMethodAttribute)attrs[0]; 
                } 
            }
            attrs = implementation.GetCustomAttributes(typeof(WebMethodAttribute), false); 
            if (attrs.Length > 0) {
                implAttribute = (WebMethodAttribute)attrs[0];
            }
            if (declAttribute == null) { 
                return implAttribute;
            } 
            if (implAttribute == null) { 
                return declAttribute;
            } 
            if (implAttribute.MessageNameSpecified) {
                throw new InvalidOperationException(Res.GetString(Res.ContractOverride, implementation.Name, implementation.DeclaringType.FullName, declaration.DeclaringType.FullName, declaration.ToString(), "WebMethod.MessageName"));
            }
            // merge two attributes 
            WebMethodAttribute attribute = new WebMethodAttribute(implAttribute.EnableSessionSpecified ? implAttribute.EnableSession : declAttribute.EnableSession);
            attribute.TransactionOption = implAttribute.TransactionOptionSpecified ? implAttribute.TransactionOption : declAttribute.TransactionOption; 
            attribute.CacheDuration = implAttribute.CacheDurationSpecified ? implAttribute.CacheDuration : declAttribute.CacheDuration; 
            attribute.BufferResponse = implAttribute.BufferResponseSpecified ? implAttribute.BufferResponse : declAttribute.BufferResponse;
            attribute.Description = implAttribute.DescriptionSpecified ? implAttribute.Description : declAttribute.Description; 
            return attribute;
        }

        // Find the MethodInfo of the interface method from the implemented method 
        internal static MethodInfo FindInterfaceMethodInfo(Type type, string signature)
        { 
            Type[] interfaces = type.GetInterfaces(); 
            // Foreach type get the interface map and then search each TargetMethod
            // till we find the right one. Once found return the corresponding interface method 
            foreach(Type i in interfaces) {
                InterfaceMapping map = type.GetInterfaceMap(i);
                MethodInfo[] targetMethods = map.TargetMethods;
                for(int j = 0; j < targetMethods.Length; j++){ 
                    if (targetMethods[j].ToString() == signature) {
                        return map.InterfaceMethods[j]; 
                    } 
                }
            } 
            return null;
        }

        internal static LogicalMethodInfo[] GetMethods(Type type) { 
            if (type.IsInterface) {
                throw new InvalidOperationException(Res.GetString(Res.NeedConcreteType, type.FullName)); 
            } 
            ArrayList list = new ArrayList();
            MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); 
            Hashtable unique = new Hashtable();
            Hashtable methodInfos = new Hashtable();
            for (int i = 0; i < methods.Length; i++) {
                Type declaringType = methods[i].DeclaringType; 
                if (declaringType == typeof(object))
                    continue; 
                if (declaringType == typeof(WebService)) 
                    continue;
                string signature = methods[i].ToString(); 
                MethodInfo declaration = FindInterfaceMethodInfo(declaringType, signature);
                WebServiceBindingAttribute binding = null;

                if (declaration != null) { 
                    object[] attrs = declaration.DeclaringType.GetCustomAttributes(typeof(WebServiceBindingAttribute), false);
                    if (attrs.Length > 0) { 
                        if (attrs.Length > 1) 
                            throw new ArgumentException(Res.GetString(Res.OnlyOneWebServiceBindingAttributeMayBeSpecified1, declaration.DeclaringType.FullName), "type");
                        binding = (WebServiceBindingAttribute)attrs[0]; 
                        if (binding.Name == null || binding.Name.Length == 0) {
                            binding.Name = declaration.DeclaringType.Name;
                        }
                    } 
                    else {
                        declaration = null; 
                    } 
                }
                else if (!methods[i].IsPublic) { 
                    continue;
                }
                WebMethodAttribute attribute = WebMethodReflector.GetAttribute(methods[i], declaration);
                if (attribute == null) 
                    continue;
 
                WebMethod webMethod = new WebMethod(declaration, binding, attribute); 
                methodInfos.Add(methods[i], webMethod);
                MethodInfo method = (MethodInfo)unique[signature]; 
                if (method == null) {
                    unique.Add(signature, methods[i]);
                    list.Add(methods[i]);
                } 
                else {
                    if (method.DeclaringType.IsAssignableFrom(methods[i].DeclaringType)) { 
                        unique[signature] = methods[i]; 
                        list[list.IndexOf(method)] = methods[i];
                    } 
                }
            }
            return LogicalMethodInfo.Create((MethodInfo[])list.ToArray(typeof(MethodInfo)), LogicalMethodTypes.Async | LogicalMethodTypes.[....], methodInfos);
        } 

        internal static void IncludeTypes(LogicalMethodInfo[] methods, XmlReflectionImporter importer) { 
            for (int i = 0; i < methods.Length; i++) { 
                LogicalMethodInfo method = methods[i];
                IncludeTypes(method, importer); 
            }
        }

        internal static void IncludeTypes(LogicalMethodInfo method, XmlReflectionImporter importer) { 
            if (method.Declaration != null) {
                importer.IncludeTypes(method.Declaration.DeclaringType); 
                importer.IncludeTypes(method.Declaration); 
            }
            importer.IncludeTypes(method.DeclaringType); 
            importer.IncludeTypes(method.CustomAttributeProvider);
        }
    }
 
    internal class WebMethod {
        internal MethodInfo declaration; 
        internal WebServiceBindingAttribute binding; 
        internal WebMethodAttribute attribute;
        internal WebMethod(MethodInfo declaration, WebServiceBindingAttribute binding, WebMethodAttribute attribute) { 
            this.declaration = declaration;
            this.binding = binding;
            this.attribute = attribute;
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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