概述
通过几个小时的尝试,终于成功实现动态调用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
最后
以上就是鲜艳楼房为你收集整理的.NET 动态调用WebService + WSE + UsernameToken的全部内容,希望文章能够帮你解决.NET 动态调用WebService + WSE + UsernameToken所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复