当前位置: 首页 > news >正文

.NET 动态调用WebService + WSE + UsernameToken

通过几个小时的尝试,终于成功实现动态调用WebService并加入WSE身份验证信息的功能。代码如下:

Code/// <summary>
		/// 动态调用WebService
		/// </summary>
		private void DynamicInvokeWebService()
		{
			//1. 创建WebClient下载WSDL信息
			WebClient web = new WebClient() ;			
			Stream stream = web.OpenRead("http://localhost/Service.asmx?wsdl") ;

			// 2. 创建和格式化 WSDL 文档。
			ServiceDescription description = ServiceDescription.Read(stream);

			// 3. 创建客户端代理代理类。
			ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
			importer.ProtocolName = "Soap"; // 指定访问协议。
			importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。

			importer.AddServiceDescription(description, null, null); // 添加 WSDL 文档。

			// 4. 使用 CodeDom 编译客户端代理类。
			CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
			CodeCompileUnit unit = new CodeCompileUnit();
			unit.Namespaces.Add(nmspace);
			
			ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); 

			//5. 修改WebService接口的基类(默认基类是SoapHttpClientProtocol),而因为使用的wse2.0,所以需要修改基类以便后面传递身份验证信息
			CodeTypeDeclaration ctDecl = nmspace.Types[0];
			nmspace.Types.Remove(ctDecl);
			ctDecl.BaseTypes[0] = new CodeTypeReference("Microsoft.Web.Services2.WebServicesClientProtocol");
			nmspace.Types.Add(ctDecl);

			//创建代码生成器
			CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider() ;			

			//6. 指定代码生成器,并获得源码
			ICodeGenerator icg = provider.CreateGenerator();
			StringBuilder srcStringBuilder = new StringBuilder();
			StringWriter sw = new StringWriter(srcStringBuilder);
			icg.GenerateCodeFromNamespace(nmspace, sw, null);
			string proxySource = srcStringBuilder.ToString();
			sw.Close();
			
			//7. 创建编译的参数
			CompilerParameters parameter = new CompilerParameters();
			//注意以下两个属性设置为false才能在多次动态调用时不会报错
			parameter.GenerateExecutable = false;
			parameter.GenerateInMemory = false;
			//用于输出dll文件,调试的时候查看结果
			//parameter.OutputAssembly = "WebService.dll"; // 可以指定你所需的任何文件名。
			parameter.ReferencedAssemblies.Add("System.dll");
			parameter.ReferencedAssemblies.Add("System.XML.dll");
			parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
			parameter.ReferencedAssemblies.Add("System.Data.dll");
			parameter.ReferencedAssemblies.Add("Microsoft.Web.Services.dll");
			parameter.ReferencedAssemblies.Add("Microsoft.Web.Services2.dll");
			
			//8. 动态编译文件
			ICodeCompiler compiler = provider.CreateCompiler();
			CompilerResults result = compiler.CompileAssemblyFromSource(parameter,proxySource) ;//compiler.CompileAssemblyFromDom(parameter, unit);			
			
			try
			{
				// 9. 检查编译是否出错
				if (!result.Errors.HasErrors)
				{
					//10. 使用 Reflection 调用 WebService。
					Assembly asm = result.CompiledAssembly;
					Type t = asm.GetType("Service"); // 如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。

					object o = Activator.CreateInstance(t)  ;
					Microsoft.Web.Services2.WebServicesClientProtocol service = o as Microsoft.Web.Services2.WebServicesClientProtocol ;
					//创建用户名安全令牌
					Microsoft.Web.Services2.Security.Tokens.UsernameToken token =
						new Microsoft.Web.Services2.Security.Tokens.UsernameToken(txtUserName.Text,txtPassword.Text,Microsoft.Web.Services2.Security.Tokens.PasswordOption.SendPlainText) ;
					//在安全凭证中添加安全令牌
					service.RequestSoapContext.Security.Tokens.Add(token) ;
					//调用WebService的方法
					MethodInfo method = t.GetMethod("AddData");
					//传递方法所需参数
					string returnString = (string)method.Invoke(o,new object[]{"","参数2"}) ;
					//获取返回结果
					this.txtResult.Text = returnString ;					
				}
				else
				{
					this.txtResult.Text = "编译出错";
				}
			}
			catch(Exception ex)
			{
				this.txtResult.Text = ex.Message ;
			}

		}

如果需要更深的了解,可以参考DynWSLib的 源码(第三方开源,可惜官方网站在却无法下载),提供老版下载地址:http://files.cnblogs.com/HarrisonYu/DynWSLib.rar


 

转载于:https://www.cnblogs.com/jerryjaord/archive/2011/04/21/2023736.html

相关文章:

  • WebService 简单介绍
  • hadoop: could only be replicated to 0 nodes, instead of 1
  • c 语言指针的用法 (1)
  • 新浪11,搜狐3,网易0---还是新浪博客访问量高呀
  • 奇怪的程序编译时间
  • 无疆_炎戎的博文导航
  • Unix哲学
  • 10245
  • 学习Linq的网站
  • Cglib的使用方法(4)--BeanCopier
  • 代码意识流——花朵数问题(八)
  • NHibernate 学习第三天 Web.config 的配置
  • 使用BIOS进行键盘输入和磁盘读写03 - 零基础入门学习汇编语言77(完)
  • MFC中的窗口绘图问题
  • 【转载】Linux下进程的建立
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Bootstrap JS插件Alert源码分析
  • css属性的继承、初识值、计算值、当前值、应用值
  • Java反射-动态类加载和重新加载
  • Python 基础起步 (十) 什么叫函数?
  • scala基础语法(二)
  • Zepto.js源码学习之二
  • 编写高质量JavaScript代码之并发
  • 和 || 运算
  • 微信小程序填坑清单
  • 正则表达式
  • hi-nginx-1.3.4编译安装
  • 如何在招聘中考核.NET架构师
  • ​flutter 代码混淆
  • (5)STL算法之复制
  • (7)STL算法之交换赋值
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (day 12)JavaScript学习笔记(数组3)
  • (javascript)再说document.body.scrollTop的使用问题
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (论文阅读11/100)Fast R-CNN
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET成年了,然后呢?
  • .NET大文件上传知识整理
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • /bin、/sbin、/usr/bin、/usr/sbin
  • :如何用SQL脚本保存存储过程返回的结果集
  • @RequestMapping处理请求异常
  • []常用AT命令解释()
  • [bzoj2957]楼房重建
  • [C++]C++入门--引用
  • [C++]STL之map
  • [CISCN2019 华东南赛区]Web4
  • [Flexbox] Using order to rearrange flexbox children
  • [IE编程] 如何编程清除IE缓存
  • [iOS]-网络请求总结
  • [Java、Android面试]_10_Java中==与equal()方法的区别?重写equal()方法?