千家信息网

动态调用webservice

发表于:2025-02-21 作者:千家信息网编辑
千家信息网最后更新 2025年02月21日,一般情况下winform调用webservice时步骤1添加服务引用---高级----添加web引用------填写url--添加web引用即可完成对webservice的引用让VS.NET环境来为我
千家信息网最后更新 2025年02月21日动态调用webservice

一般情况下winform调用webservice时步骤

1添加服务引用---高级----添加web引用------填写url--添加web引用即可完成对webservice的引用

让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务。

如果需要动态调用WebService,要实现这样的功能:

public static object InvokeWebService(string url, string methodname,object[] args)

其中,url是Web服务的地址,methodname是要调用服务方法名,args是要调用Web服务所需的参数,返回值就是web服务返回的结果了。

要实现这样的功能,你需要这几个方面的技能:反射、CodeDom、编程使用C#编译器、WebService。在了解这些知识后,就可以容易的实现web服务的动态调用了:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

using System.Net;

using System.CodeDom;

using System.CodeDom.Compiler;

using System.Web.Services.Description;

using Microsoft.CSharp;

namespace NetbankTMP

{

public static class WebServiceHelper

{

///

/// 动态调用WebService

///

/// WebService地址

/// 方法名(模块名)

/// 参数列表,无参数为null

/// object

public static object InvokeWebService(string url, string methodname, object[] args)

{

return InvokeWebService(url, null, methodname, args);

}

///

/// 动态调用WebService

///

/// WebService地址

/// 类名

/// 方法名(模块名)

/// 参数列表

/// object

public static object InvokeWebService(string url, string classname, string methodname, object[] args)

{

string @namespace = "fangqm.Netbank.WebService.webservice";

if (classname == null || classname == "")

{

classname = WebServiceHelper.GetClassName(url);

}

//获取服务描述语言(WSDL)

WebClient wc = new WebClient();

Stream stream = wc.OpenRead(url+"?WSDL");//【1】

ServiceDescription sd = ServiceDescription.Read(stream);//【2】

ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();//【3】

sdi.AddServiceDescription(sd, "", "");

CodeNamespace cn = new CodeNamespace(@namespace);//【4】

//生成客户端代理类代码

CodeCompileUnit ccu = new CodeCompileUnit();//【5】

ccu.Namespaces.Add(cn);

sdi.Import(cn, ccu);

CSharpCodeProvider csc = new CSharpCodeProvider();//【6】

ICodeCompiler icc = csc.CreateCompiler();//【7】

//设定编译器的参数

CompilerParameters cplist = new CompilerParameters();//【8】

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);//【9】

if (true == cr.Errors.HasErrors)

{

System.Text.StringBuilder sb = new StringBuilder();

foreach (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 bj = Activator.CreateInstance(t);//【10】

System.Reflection.MethodInfo mi = t.GetMethod(methodname);//【11】

return mi.Invoke(obj, args);

}

private static string GetClassName(string url)

{

//假如URL为"http://localhost/InvokeService/Service1.asmx"

//最终的返回值为 Service1

string[] parts = url.Split('/');

string[] pps = parts[parts.Length - 1].Split('.');

return pps[0];

}

}

}

上面的注释已经很好的说明了各代码段的功能,下面给个例子看看,这个例子是通过访问http://www.webservicex.net/globalweather.asmx服务来获取各大城市的天气状况。

string url="http://www.webservicex.net/globalweather.asmx";

string[] args=newstring[2] ;

args[0]=this.textBox_CityName.Text ;

args[1]="China";

object result=WebServiceHelper.InvokeWebService(url ,"GetWeather",args) ;

this.label_Result.Text=result.ToString() ;

如果没有参数,则参数为null

上述的例子中,调用web服务使用了两个参数,第一个是城市的名字,第二个是国家的名字,Web服务返回的是XML文档,可以从其中解析出温度、风力等天气情况。

关于这段代码的注释

【2】 ServiceDescription类提供一种方法,以创建和格式化用于描述 XML Web services 的有效的 Web 服务描述语言 (WSDL) 文档文件,该文件是完整的,具有适当的命名空间、元素和特性。无法继承此类。

ServiceDescription.Read 方法 (Stream) 通过直接从 Stream实例加载 XML 来初始化ServiceDescription类的实例。

【3】 ServiceDescriptionImporter 类 公开一种为 XML Web services 生成客户端代理类的方法。

ServiceDescriptionImporter.AddServiceDescription 方法将指定的ServiceDescription添加到要导入的ServiceDescriptions值的集合中。

【4】 CodeNamespace表示命名空间声明。

【5】 CodeCompileUnit会提供一个CodeDOM程式圆形的容器,CodeCompileUnit含有一个集合,可以储存含有CodeDOM原始程式码原形,专案参考的组件集合以及专案组件属性集合的CodeNamespace物件。

【6】 CSharpCodeProvider类提供存取C#程式码产生器和程式码编译器的执行个体。

【7】 取得C#程式码编译器的执行个体

【8】 创建编译器的参数实例

【9】 CompilerResults表示从编译器返回的编译结果。使用指定的编译器设定,根据CodeCompileUnit物件之指定阵列所包含的System.CodeDom树状结构,编译一个组件。

【10】 Activator类包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。无法继承此类Activator.CreateInstance 方法 使用与指定参数匹配程度最高的构造函数创建指定类型的实例。

【11】 MethodInfo 的实例可以通过调用GetMethods或者Type对象或派生自Type的对象的GetMethod方法来获取,还可以通过调用表示泛型方法定义的 MethodInfo 的MakeGenericMethod方法来获取。


方法 服务 参数 编译 编译器 实例 程式 代理 动态 对象 生成 代码 例子 功能 地址 组件 C# 专案 个体 可以通过 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 武汉学互联网科技专业的大学 戴尔服务器开启虚拟化 fifa22球员数据库工具 b站服务器连接中断 网络安全服务排名 什么是系统安装服务器 iebook如何发布本地服务器 数据库中可选择数据类型 系统数据库msdb的全称 查看当前系统内所有可用的数据库 南昌网络安全员证在哪里 想学软件开发与设计 修改数据库密码的语句 网警犹如清道夫守护网络安全 软件开发 业务分析 王者荣耀寒冰之心是哪个服务器 暨南大学计算机与网络安全 学生网络安全基础知识 崇左市网络安全工作专题会议 浅论面向对象软件开发过程 php要用数据库吗 企业nas服务器有什么用 黑客攻击数据库的第一步 公司服务器管理员哪些方面 网络技术基础 论文 一加手机服务器繁忙 帆软决策系统连接外部数据库 负责客户现场网络安全设备 暨南大学计算机与网络安全 虚拟服务器安装系统教程
0