c#中动态编译wsdl并调用接口
来源:互联网 发布:linux grep命令详解 编辑:程序博客网 时间:2024/06/15 13:24
由于工作中需要,接触到了编译wsdl。
这次记录下 动态编译wsdl生成代理类dll,并调用接口测试:
直接上代码吧
using System;using System.Collections.Generic;using System.Text;using System.Net;using System.IO;using System.Web.Services.Description;using System.CodeDom;using Microsoft.CSharp;using System.CodeDom.Compiler;namespace WebserviceCallingTest{ class WebserviceCalling { /// <summary> /// 实例化WebServices /// </summary> /// <param name="url">WebServices地址</param> /// <param name="methodname">调用的方法</param> /// <param name="args">把webservices里需要的参数按顺序放到这个object[]里</param> public static object InvokeWebService(string url, string methodname, object[] args) { //这里的namespace是需引用的webservices的命名空间,也可以加一个参数从外面传进来。 string @namespace = "MyWebserviceTest"; Console.WriteLine("定义命名空间:" + @namespace); try { Console.WriteLine("开始获取wsdl..."); //获取WSDL WebClient wc = new WebClient(); Console.WriteLine("开始获取流数据..."); Stream stream = wc.OpenRead(url + "?wsdl"); ServiceDescription sd = ServiceDescription.Read(stream); Console.WriteLine("格式化流数据..."); string classname = sd.Services[0].Name; Console.WriteLine("获取包含在流中的service集合中service[0].name:" + classname); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); Console.WriteLine("建立生成代理类功能类对象的实例..."); sdi.AddServiceDescription(sd, "", ""); /* * sdi.ProtocolName = "SOAP"; * 这里说明下,协议类型有很多种,主要是 SOAP 和 SOAP12 * 如果这里不配置,可能会出现两种异常: * 1. XML文档中< X,X >有错误 * 2. 命名空间 http://xxxxx/xxxx 无法导入到 xxxxxxxx 中。 * * 另:如果配置了某一值,则只能使用这个值所代表的协议类型 * 建议:可以使用参数来传递协议类型。 */ sdi.ProtocolName = "SOAP"; Console.WriteLine("配置访问XML的协议为:" + sdi.ProtocolName ); Console.WriteLine("将流数据加入实例中..."); CodeNamespace cn = new CodeNamespace(@namespace); Console.WriteLine("生成命名空间对象..."); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit(); Console.WriteLine("建立CodeDom容器对象..."); ccu.Namespaces.Add(cn); Console.WriteLine("为容器添加命名空间..."); sdi.Import(cn, ccu); Console.WriteLine("将命名空间和容器导入wsdl流中..."); CSharpCodeProvider csc = new CSharpCodeProvider(); Console.WriteLine("建立C#代码生成器和编译器对象..."); //ICodeCompiler icc = csc.CreateCompiler(); //设定编译参数 CompilerParameters cplist = new CompilerParameters(); Console.WriteLine("设置编译参数..."); 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"); //这里的字段OutputAssembly可配置也可不配置,配置后下面的编译器对象将按照配置的路径将wsdl生成.dll文件 cplist.OutputAssembly = System.IO.Directory.GetCurrentDirectory() + "\\" + classname + ".dll"; Console.WriteLine("根据编译器对象按照编译参数对象和容器对象设置编译生成代理类对象..."); //编译代理类 CompilerResults cr = csc.CompileAssemblyFromDom(cplist, ccu); Console.WriteLine("编译完成..."); Console.WriteLine("检测编译是否产生错误..."); if (File.Exists(System.IO.Directory.GetCurrentDirectory() + "\\" + classname + ".dll")) { Console.WriteLine(classname + ".dll" + "文件生成..."); } 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()); } Console.WriteLine("开始调用编译完的程序集..."); //生成代理实例,并调用方法 /* * 这里使用 System.Reflection.Assembly assembly = cr.CompiledAssembly 其实并不保险,assembly默认调用的是当前的程序集, * 也就是默认调用的是WebserviceCalling(执行动态编译wsdl的程序集,就是本文),而不是编译成功的 Service.dll * 所以,当执行assembly.GetType(@namespace + "." + classname, true, true)时,得到的 Type t 为null。 */ Console.WriteLine("建立程序集对象..."); //System.Reflection.Assembly assembly = cr.CompiledAssembly; /* * 借用大神http://www.cnblogs.com/keyyang/p/3803920.html的解决办法 * 先加载 Service.dll * Assembly asmb = Assembly.LoadFrom(classname + ".dll") ; * 再获取程序集中的类型对象 * Type supType = asmb.GetType(@namespace + "." + classname) ; */ System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(classname + ".dll"); Type t = assembly.GetType(@namespace + "." + classname, true, true); Console.WriteLine("获取程序集中" + @namespace + "." + classname + "中的类型对象..."); object obj = Activator.CreateInstance(t); Console.WriteLine("建立该对象实例..."); System.Reflection.MethodInfo mi = t.GetMethod(methodname); Console.WriteLine("获取名为" + methodname + "的方法的信息....\n" + mi.ToString()); Console.WriteLine("开始调用该方法..."); return mi.Invoke(obj, args); } catch { return null; } } static void Main(string[] args) { String url = "http://192.168.5.140:8090/Service1.asmx" ; String methodname = "Add" ; String param = "1,2" ; Console.WriteLine("调用方法:" + methodname + ",传递参数:" + param.ToString()); Console.WriteLine("得到结果:" + InvokeWebService(url, methodname, param.Split(',')).ToString()); Console.ReadLine(); } }}
小弟我是刚刚开始学习编程,文章中所说为自己理解,如有不对的地方,请各位大神指正。
阅读全文
1 0
- c#中动态编译wsdl并调用接口
- c#中手动及半自动编译wsdl并调用
- wsdl接口调用
- c#中接口实现类的动态调用实现
- 根据wsdl调用webservice接口
- C#利用反射动态加载DLL(C#)并调用其中的接口
- 【经典实例】利用C#反射动态编译代码,创建类的实例,并调用其成员
- C#调用C++动态库接口
- WSDL编译为C#代码
- C#动态编译代码并执行
- C#动态创建类实例并调用
- C#中动态编译应用程序
- C#中动态编译应用程序
- VS2013调用C#编译的动态库
- 关于vs2010下编译dll动态库,JNA接口在java中调用的问题
- 通过代理接口在内存中动态生成代理类源代码并编译实现的真正动态代理
- C# 代码中调用ActiveX控件更新接口造成编译错误的问题
- C# 中动态调用C++动态链接
- PostgreSQL psql 终端命令
- 最长回文子串---Manacher算法
- C#泛型方法的反射
- WEB基础
- WUST OJ 1590: As Many Princesses as Possible(树形DP)
- c#中动态编译wsdl并调用接口
- 混合运算与类型转换规律
- 第3章:微服务治理
- JAVA面试题------根据所给格式将字符串中单词倒置
- 作业
- ubuntu下sudo apt-get update出错:E: Could not get lock /var/lib/apt/lists/lock
- 绘制ggplot相位图高级标识
- (HDU
- 七层网络模型与四层网络模型