动态调用WebService

 

通过web service url调用web method,如果web method返回的是.net通用类型,可以不用添加web引用到工程。比如调用的web method返回的是DataTable类型。

 

 // Client Console Application

using System;

using System.Data;

using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Net;
using System.IO;
using System.Web.Services.Protocols;
using System.Web.Services.Description;
using System.CodeDom;
using System.CodeDom.Compiler;

namespace ConsoleApplication
{

 

class Program
    {
        static void Main(string[] args)
        {
            string WebUrl = "http://localhost/mywebservice.asmx";
            string myFirstName = "123";
            string myLastName = "456";
            DataTable dt = new DataTable();
            try
            {
                dt = (DataTable)TestWebService.InvokeWebService(WebUrl, "MyWebService", "MyWebService", "GetMyDataTable", CredentialsType.None, true, new Type[] { typeof(string), typeof(string) }, myFirstName, myLastName);
                Console.WriteLine(dt.Rows.Count.ToString());
            }
            catch (Exception)
            {               
                throw;
            }           
        }
    }


    public enum CredentialsType
    {
        None,
        Windows
    }

    public class TestWebService
    {
        private static Dictionary<string, Assembly> assemblyCache = new Dictionary<string, Assembly>();
        private static Assembly assembly = null;

        /// <summary>
        /// Dynamically invoke a web method from web service assembly.
        /// </summary>
        /// <param name="url">Web Service URL, e.g. http://localhost/MyWebService.asmx </param>
        /// <param name="nameSpace">Web Service NameSpace, e.g. MyWebServiceNameSpace</param>
        /// <param name="typeName">Web Service TypeName, e.g. MyWebServiceClass</param>
        /// <param name="methodName">The name of invoked web method</param>
        /// <param name="credentials">The credential of SoapHttpClientProtocol</param>
        /// <param name="assemblyFlag">True - Compiler web service proxy assembly, False - Get executing web service assembly</param>
        /// <param name="parmsTypes">The type of invoked web method parameters</param>
        /// <param name="args">The value of invoked web method parameters</param>
        /// <returns></returns>
        public static object InvokeWebService(string url, string nameSpace, string typeName, string methodName, CredentialsType credentials, bool assemblyFlag, Type[] parmsTypes, params object[] args)
        {
            string fullTypeName = nameSpace + "." + typeName;
            if (parmsTypes == null)
            {
                parmsTypes = new Type[0];
            }
            if (args == null)
            {
                args = new object[0];
            }
            if (parmsTypes.Length != args.Length)
            {
                throw new Exception("The count of method parameters and types are not equal.");
            }

            try
            {
                if (assemblyCache.Count == 0 || !assemblyCache.ContainsKey(fullTypeName))
                {
                    if (assemblyFlag)
                    {
                        assembly = CompilerWebProxyAssembly(url, nameSpace, credentials);
                    }
                    else
                    {
                        assembly = Assembly.GetExecutingAssembly();
                    }
                    assemblyCache.Add(fullTypeName, assembly);                   
                }

                assembly = assemblyCache[fullTypeName];
                if (assembly == null)
                {
                    throw new Exception("Unable to get executing assembly.");
                }

                Type actionType = assembly.GetType(fullTypeName);
                if (actionType == null)
                {
                    throw new Exception("Unable to load the type: " + fullTypeName);
                }

                MethodInfo methodInfo = actionType.GetMethod(methodName, parmsTypes);

                if (methodInfo == null)
                {
                    throw new Exception("Unable to load the method: " + methodName);
                }

                object obj = assembly.CreateInstance(actionType.FullName);

                switch (credentials)
                {
                    case CredentialsType.None:
                        break;
                    case CredentialsType.Windows:
                        SoapHttpClientProtocol protocol = (SoapHttpClientProtocol)obj;
                        protocol.Credentials = CreateWindowsCredentials(url);
                        break;
                    default:
                        break;
                }

                return methodInfo.Invoke(obj, args);
            }
            catch (Exception ex)
            {
                throw new Exception("Invoke web service failed.\n" + ex.Message);
            }
        }

        private static Assembly CompilerWebProxyAssembly(string url, string nameSpace, CredentialsType credentials)
        {
            try
            {
                WebClient webClient = CreateWebServiceClient(url, credentials);
                Stream stream = webClient.OpenRead(url + "?WSDL");

                ServiceDescription description = ServiceDescription.Read(stream);

                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
                importer.ProtocolName = "Soap";  // network protocol
                importer.Style = ServiceDescriptionImportStyle.Client; // generate client proxy
                importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties | System.Xml.Serialization.CodeGenerationOptions.GenerateNewAsync;
                importer.AddServiceDescription(description, null, null); // add wsdl document

                CodeNamespace space = new CodeNamespace(nameSpace); // add namespace for proxy class
                CodeCompileUnit unit = new CodeCompileUnit();
                unit.Namespaces.Add(space);

                ServiceDescriptionImportWarnings warnings = importer.Import(space, unit);
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

                CompilerParameters parameters = new CompilerParameters();
                parameters.GenerateExecutable = false;
                parameters.GenerateInMemory = true;
                parameters.ReferencedAssemblies.Add("System.dll");
                parameters.ReferencedAssemblies.Add("System.XML.dll ");
                parameters.ReferencedAssemblies.Add("System.Web.Services.dll ");
                parameters.ReferencedAssemblies.Add("System.Data.dll ");

                CompilerResults results = provider.CompileAssemblyFromDom(parameters, unit);
                if (!results.Errors.HasErrors)
                {
                    return results.CompiledAssembly;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Complie web proxy assembly failed.\n" + ex.Message);
            }
        }

        private static WebClient CreateWebServiceClient(string url, CredentialsType credentials)
        {
            try
            {
                WebClient webClient = new WebClient();

                // Extension other credentials
                switch (credentials)
                {
                    case CredentialsType.None:
                        break;
                    case CredentialsType.Windows:
                        ICredentials windowsCredentials = CreateWindowsCredentials(url);
                        webClient.Credentials = windowsCredentials;
                        break;
                    default:
                        break;
                }

                return webClient;
            }
            catch (Exception ex)
            {
                throw new Exception("Create web service client failed." + ex.Message);
            }
        }

        private static ICredentials CreateWindowsCredentials(string url)
        {
            try
            {
                string domain = "123";
                string username = "123";
                string password = "123";

                NetworkCredential credential = new NetworkCredential(username, password, domain);
                CredentialCache cache = new CredentialCache();
                cache.Add(new Uri(url), "NTLM", credential);

                return cache;
            }
            catch (Exception ex)
            {
                throw new Exception("Create windows credentials failed." + ex.Message);
            }
        }
    }
}


 

 

 

// My Web Service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;

namespace MyWebService
{
    /// <summary>
    /// Summary description for MyWebService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    // [System.Web.Script.Services.ScriptService]
    public class MyWebService : System.Web.Services.WebService
    {
        [WebMethod]
        public DataTable GetMyDataTable(string firstName, string lastName)
        {
            DataTable dt = new DataTable(firstName + lastName);

            return dt;
        }
    }
}

posted on 2010-08-02 11:35  IORICC  阅读(433)  评论(0编辑  收藏  举报