• C# 动态调用 WebService (转)


          在 Visual Studio 中客户端程序可以添加服务引用来调用 WebService,这样 Visual Studio 会生成与之相关的代理类,通过这个代理类可以很方便的访问所需要的服务。

          如果服务端 WebService 的 url 地址发生了变化,客户端就必须重新更新和编译服务引用,这样操作起来不方便。这里介绍一种动态调用 WebService 的方法,当服务变化时,

    客户端可以不用重新编译程序,只需修改配置文件。

           核心方法如下(url 是WebService 的地址,methodname是要调用服务方法名,args是要调用Web服务所需的参数,返回值就是web服务返回的结果):

    public static object InvokeWebService(string url, string methodname, object[] args)

          相关技术:反射、CodeDom、编程使用C#编译器、WebService

    using Microsoft.CSharp;
    using System;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Web.Services.Description;
    using System.Xml;
    
    namespace PHY.BOP.Mvc4App.App_Start
    {
        public class WebServiceHelper
        {
            #region InvokeWebService
            //动态调用web服务
            public static object InvokeWebService(string url, string methodname, object[] args)
            {
                return WebServiceHelper.InvokeWebService(url, null, methodname, args);
            }
    
            public static object InvokeWebService(string url, string classname, string methodname, object[] args)
            {
                string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
                if ((classname == null) || (classname == ""))
                {
                    classname = WebServiceHelper.GetWsClassName(url);
                }
    
                try
                {
                    //使用 Stream 对象,创建和格式化 WSDL 文档
                    //WebClient wc = new WebClient();
                    //Stream stream = wc.OpenRead(url + "?WSDL");
                    //ServiceDescription sd = ServiceDescription.Read(stream);
    
                    //使用 XmlTextReader 对象,创建和格式化 WSDL 文档
                    XmlTextReader reader = new XmlTextReader(url + "?wsdl");                
                    ServiceDescription sd = ServiceDescription.Read(reader);
    
                    
                    ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
                    sdi.AddServiceDescription(sd, "", "");
                    CodeNamespace cn = new CodeNamespace(@namespace);
    
                    //生成客户端代理类代码
                    CodeCompileUnit ccu = new CodeCompileUnit();
                    ccu.Namespaces.Add(cn);
                    sdi.Import(cn, ccu);
                    CSharpCodeProvider csc = new CSharpCodeProvider();
                    ICodeCompiler icc = csc.CreateCompiler();
    
                    //设定编译参数
                    CompilerParameters cplist = new CompilerParameters();
                    cplist.GenerateExecutable = false;
                    cplist.GenerateInMemory = true;
                    cplist.ReferencedAssemblies.Add("System.dll");
                    cplist.ReferencedAssemblies.Add("System.XML.dll");
                    cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                    cplist.ReferencedAssemblies.Add("System.Data.dll");
    
                    //编译代理类
                    CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
                    if (true == cr.Errors.HasErrors)
                    {
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
                        foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                        {
                            sb.Append(ce.ToString());
                            sb.Append(System.Environment.NewLine);
                        }
                        throw new Exception(sb.ToString());
                    }
    
                    //生成代理实例,并调用方法
                    System.Reflection.Assembly assembly = cr.CompiledAssembly;
                    Type t = assembly.GetType(@namespace + "." + classname, true, true);
                    object obj = Activator.CreateInstance(t);
                    System.Reflection.MethodInfo mi = t.GetMethod(methodname);
    
                    return mi.Invoke(obj, args);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
                }
            }
    
            private static string GetWsClassName(string wsUrl)
            {
                string[] parts = wsUrl.Split('/');
                string[] pps = parts[parts.Length - 1].Split('.');
    
                return pps[0];
            }
            #endregion
    
            //通过webservice获取国家对应的城市的名称
            private static void Main(string[] args)
            {
                string url = "http://www.webservicex.net/globalweather.asmx";
                args = new string[1];
                args[0] = "China";
                object result = WebServiceHelper.InvokeWebService(url, "GetCitiesByCountry", args);
                System.Console.Write(result.ToString());
            }
        }
    }

     

    参考资源:

    http://www.cnblogs.com/ruochen/archive/2007/12/11/990427.html

    http://linglong117.blog.163.com/blog/static/277145472009127514463/

  • 相关阅读:
    mysql修改时区time_zone
    magento的布局(layouts)、模块(block)、模板(templates)
    唯品会消息网关的架构定位
    Java应用一般架构
    maven打包命令
    端口查看与封杀
    java程序优化
    高并发下竞争的资源
    java中的多线程高并发与负载均衡的用途
    Web负载均衡的几种实现方式
  • 原文地址:https://www.cnblogs.com/hellowzl/p/6395121.html
Copyright © 2020-2023  润新知