C#动态调用 WebServer

using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web.Services;
using System.Web.Services.Description;

namespace 练习2
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://localhost:8096/WebService1.asmx";//可写入配置文件
            //客户端代理服务命名空间,可以设置成需要的值。
            string ns = string.Format("ProxyServiceReference");

            // 获取WSDL
            WebClient wc = new WebClient();
            Stream stream = wc.OpenRead(url + "?WSDL");//读取 SOAP说名文档
            ServiceDescription sd = ServiceDescription.Read(stream);//服务的描述信息都可以通过ServiceDescription获取
            string classname = sd.Services[0].Name;

            //公开一种为 XML Web services 生成客户端代理类的方法。
            ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
            sdi.AddServiceDescription(sd, "", "");
            CodeNamespace cn = new CodeNamespace(ns);//初始化一个命名空间

            //生成客户端代理类代码
            CodeCompileUnit ccu = new CodeCompileUnit();
            ccu.Namespaces.Add(cn);//添加命名空间

           //导入指定的 System.Web.Services.Description.ServiceDescriptionImporter.ServiceDescriptions    值,并将按照 System.Web.Services.Description.ServiceDescriptionImporter.Style 属性的指定来生成代码。
            sdi.Import(cn, ccu);//参数1:命名空间。参数2:生成webserver的类


            #region 动态编译
            CSharpCodeProvider csc = new CSharpCodeProvider();//提供对 C# 代码生成器和代码编译器的实例的访问。

            //设定编译参数 .CompilerParameters 表示用于调用编译器的参数
            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 = csc.CompileAssemblyFromDom(cplist, ccu);
            if (cr.Errors.HasErrors == true)
            {
                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());
            } 
            #endregion

            //生成代理实例,并调用方法
            Assembly assembly = cr.CompiledAssembly;
            Type t = assembly.GetType(ns + "." + classname, true, true);
            //Activator:包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。 此类不能被继承。
            object obj = Activator.CreateInstance(t);//使用指定类型的默认构造函数来创建该类型的实例。

            



            //调用HelloWorld方法
            MethodInfo helloWorld = t.GetMethod("HelloWorld");
            object helloWorldReturn = helloWorld.Invoke(obj, null);//要传入调用对象,object类型,由 75行代码生成
            Console.WriteLine("调用HelloWorld方法,返回{0}", helloWorldReturn.ToString());

            //获取HelloWorld方法的参数
            ParameterInfo[] helloWorldParamInfos = helloWorld.GetParameters();
            Console.WriteLine("HelloWorld方法有{0}个参数:", helloWorldParamInfos.Length);
            foreach (ParameterInfo paramInfo in helloWorldParamInfos)
            {
                Console.WriteLine("参数名:{0},参数类型:{1}", paramInfo.Name, paramInfo.ParameterType.Name);
            }

            //获取HelloWorld返回的数据类型
            string helloWorldReturnType = helloWorld.ReturnType.Name;
            Console.WriteLine("HelloWorld返回的数据类型是{0}", helloWorldReturnType);

            
            Console.WriteLine("\n==============================================================");



            //调用Add方法
            MethodInfo add = t.GetMethod("Add");
            int a = 10, b = 20;//Add方法的参数
            object[] addParams = new object[] { a, b };//方法 参数
            object addReturn = add.Invoke(obj, addParams);
            Console.WriteLine("调用Add方法,{0} + {1} = {2}", a, b, addReturn.ToString());
            //获取Add方法的参数
            ParameterInfo[] addParamInfos = add.GetParameters();
            Console.WriteLine("Add方法有{0}个参数:", addParamInfos.Length);
            foreach (ParameterInfo paramInfo in addParamInfos)
            {
                Console.WriteLine("参数名:{0},参数类型:{1}", paramInfo.Name, paramInfo.ParameterType.Name);
            }

            //获取Add返回的数据类型
            string addReturnType = add.ReturnType.Name;
            Console.WriteLine("Add返回的数据类型:{0}", addReturnType);



            
            Console.WriteLine("\n==============================================================");

            //调用GetUsers方法
            MethodInfo GetUser = t.GetMethod("GetUsers");
            //参数obj: 对其调用方法或构造函数的对象。 如果方法是静态的,则忽略此参数。 如果构造函数是静态的,则此参数必须为 null 或定义该构造函数的类的实例。
            object getUserReulst = GetUser.Invoke(obj, null);
            Console.WriteLine("调用GetUsers方法返回数据集如下:");
            DataSet data = getUserReulst as DataSet;
            DataTable table = data.Tables[0];
            foreach (DataRow row in table.Rows)
            {
                Console.WriteLine(row[0]+","+row[1]+","+row[2]);
            }

            //获取GetUsers方法的参数
            ParameterInfo[] getUserParameters = GetUser.GetParameters();
            Console.WriteLine("GetUsers方法有{0}个参数",getUserParameters.Length);
            foreach (ParameterInfo item in getUserParameters)
            {
                Console.WriteLine("参数名称:{0},参数类型:{1}",item.Name,item.ParameterType.Name);
            }

            //获取GetUsers方法的返回数据类型
            string getUserReturnType = GetUser.ReturnType.FullName;
            Console.WriteLine("GetUser方法返回数据类型是:"+ getUserReturnType);

            Console.ReadKey();

        }
    }
}

参考 博客地址:https://www.cnblogs.com/91loveme/p/3533764.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值