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

  • 相关阅读:
    飞思卡尔IMX6处理器的GPIO配置方式
    批处理清除VisualStudio解决方案文件夹
    总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告
    详解Linux2.6内核中基于platform机制的驱动模型 (经典)
    [驱动注册]platform_driver_register()与platform_device_register()
    机器人系统常用仿真软件介绍效果与评价指标
    WINCE的批处理
    项目开发中的人月及如何计算
    常用的六个富文本编辑器
    如何获取公众号里面的歌曲
  • 原文地址:https://www.cnblogs.com/hellowzl/p/6395121.html
Copyright © 2020-2023  润新知