C# 调用WebService的方法
一、前言
在日常工作中,如果涉及到与第三方进行接口对接,有的会使用webservice的方式,这篇文章主要讲解在.net framework中如何调用webservice。首先我们创建一个webservice,里面有两个方法:一个无参的方法,一个有参的方法:
创建好了webservice以后,把webservice部署到iis上,并确保可以访问
二、静态引用
这种方式是通过添加静态引用的方式调用webservice。首先创建一个winform程序,界面上有一个按钮,点击按钮调用webservice:
然后添加静态引用。在要调用webservice的项目上选择引用,然后右键选择“添加服务引用”,如下图所示:
然后输入iis上部署的webservice地址:
最后点击“确定”按钮即可完成静态引用webservice,添加完成以后的项目结构如下图所示:
添加完引用以后,就可以编写代码了:
/// <summary> /// 静态调用webservice /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_static_click(object sender, eventargs e) { // 实例化类 callwebservice.testwebsoapclient client = new callwebservice.testwebsoapclient(); // 调用无参的helloworld方法 string value1= client.helloworld(); // 调用有参的方法 string value2 = client.test("有参方法"); // 输出 messagebox.show($"无参方法返回值:{value1},有参方法返回值:{value2}"); }
运行程序测试:
这样就可以实现调用webservice了。
三、动态调用
上面我们说了如何使用静态引用的方式调用webservice,但是这种方式有一个缺点:如果发布的webservice地址改变,那么就要重新添加webservice的引用。如果是现有的webservice发生了改变,也要更新现有的服务引用,这需要把代码放到现场才可以。那么有没有什么方式可以解决这种问题呢?那就是使用动态调用webservice的方法。
我们在配置文件里面添加配置,把webservice的地址、webservice提供的类名、要调用的方法名称,都写在配置文件里面:
<appsettings> <!--webservice地址--> <add key="webserviceaddress" value="http://localhost:9008/testweb.asmx"/> <!--webservice提供的类名--> <add key="classname" value="testweb"/> <!--webservice方法名--> <add key="methodname" value="test"/> <!--存放dll文件的地址--> <add key="filepath" value="e:\test"/> </appsettings>
在界面上添加一个按钮,点击按钮可以动态调用webservice,新建一个帮助类:
using system; using system.codedom; using system.codedom.compiler; using system.io; using system.net; using system.text; using system.web; using system.web.caching; using system.web.services.description; using system.xml.serialization; namespace webservicedemo { public class webservicehelper { /// <summary> /// 生成dll文件保存到本地 /// </summary> /// <param name="url">webservice地址</param> /// <param name="classname">类名</param> /// <param name="methodname">方法名</param> /// <param name="filepath">保存dll文件的路径</param> public static void createwebservicedll(string url,string classname, string methodname,string filepath ) { // 1. 使用 webclient 下载 wsdl 信息。 webclient web = new webclient(); stream stream = web.openread(url + "?wsdl"); // 2. 创建和格式化 wsdl 文档。 servicedescription description = servicedescription.read(stream); //如果不存在就创建file文件夹 if (directory.exists(filepath) == false) { directory.createdirectory(filepath); } if (file.exists(filepath + classname + "_" + methodname + ".dll")) { //判断缓存是否过期 var cachevalue = httpruntime.cache.get(classname + "_" + methodname); if (cachevalue == null) { //缓存过期删除dll file.delete(filepath + classname + "_" + methodname + ".dll"); } else { // 如果缓存没有过期直接返回 return; } } // 3. 创建客户端代理代理类。 servicedescriptionimporter importer = new servicedescriptionimporter(); // 指定访问协议。 importer.protocolname = "soap"; // 生成客户端代理。 importer.style = servicedescriptionimportstyle.client; importer.codegenerationoptions = codegenerationoptions.generateproperties | codegenerationoptions.generatenewasync; // 添加 wsdl 文档。 importer.addservicedescription(description, null, null); // 4. 使用 codedom 编译客户端代理类。 // 为代理类添加命名空间,缺省为全局空间。 codenamespace nmspace = new codenamespace(); codecompileunit unit = new codecompileunit(); unit.namespaces.add(nmspace); servicedescriptionimportwarnings warning = importer.import(nmspace, unit); codedomprovider provider = codedomprovider.createprovider("csharp"); compilerparameters parameter = new compilerparameters(); parameter.generateexecutable = false; // 可以指定你所需的任何文件名。 parameter.outputassembly = filepath + classname + "_" + methodname + ".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"); // 生成dll文件,并会把webservice信息写入到dll里面 compilerresults result = provider.compileassemblyfromdom(parameter, unit); if (result.errors.haserrors) { // 显示编译错误信息 system.text.stringbuilder sb = new stringbuilder(); foreach (compilererror ce in result.errors) { sb.append(ce.tostring()); sb.append(system.environment.newline); } throw new exception(sb.tostring()); } //记录缓存 var objcache = httpruntime.cache; // 缓存信息写入dll文件 objcache.insert(classname + "_" + methodname, "1", null, datetime.now.addminutes(5), timespan.zero, cacheitempriority.high, null); } } }
动态调用webservice代码:
/// <summary> /// 动态调用webservice /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_dynamic_click(object sender, eventargs e) { // 读取配置文件,获取配置信息 string url = configurationmanager.appsettings["webserviceaddress"]; string classname = configurationmanager.appsettings["classname"]; string methodname = configurationmanager.appsettings["methodname"]; string filepath = configurationmanager.appsettings["filepath"]; // 调用webservicehelper webservicehelper.createwebservicedll(url, classname, methodname, filepath); // 读取dll内容 byte[] filedata = file.readallbytes(filepath + classname + "_" + methodname + ".dll"); // 加载程序集信息 assembly asm = assembly.load(filedata); type t = asm.gettype(classname); // 创建实例 object o = activator.createinstance(t); methodinfo method = t.getmethod(methodname); // 参数 object[] args = {"动态调用webservice" }; // 调用访问,获取方法返回值 string value = method.invoke(o, args).tostring(); //输出返回值 messagebox.show($"返回值:{value}"); }
程序运行结果:
如果说类名没有提供,可以根据url来自动获取类名:
/// <summary> /// 根据webservice的url地址获取classname /// </summary> /// <param name="wsurl">webservice的url地址</param> /// <returns></returns> private string getwsclassname(string wsurl) { string[] parts = wsurl.split('/'); string[] pps = parts[parts.length - 1].split('.'); return pps[0]; }
以上就是c# 调用webservice的方法的详细内容,更多关于c# 调用webservice的资料请关注其它相关文章!