欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 调用WebService的方法

程序员文章站 2022-06-28 12:15:16
一、前言在日常工作中,如果涉及到与第三方进行接口对接,有的会使用webservice的方式,这篇文章主要讲解在.net framework中如何调用webservice。首先我们创建一个webserv...

一、前言

在日常工作中,如果涉及到与第三方进行接口对接,有的会使用webservice的方式,这篇文章主要讲解在.net framework中如何调用webservice。首先我们创建一个webservice,里面有两个方法:一个无参的方法,一个有参的方法:

C# 调用WebService的方法

创建好了webservice以后,把webservice部署到iis上,并确保可以访问

二、静态引用

这种方式是通过添加静态引用的方式调用webservice。首先创建一个winform程序,界面上有一个按钮,点击按钮调用webservice:

C# 调用WebService的方法

然后添加静态引用。在要调用webservice的项目上选择引用,然后右键选择“添加服务引用”,如下图所示:

C# 调用WebService的方法

然后输入iis上部署的webservice地址:

C# 调用WebService的方法

最后点击“确定”按钮即可完成静态引用webservice,添加完成以后的项目结构如下图所示:

C# 调用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}");
}

运行程序测试:

C# 调用WebService的方法

这样就可以实现调用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}");
}

程序运行结果:

C# 调用WebService的方法

如果说类名没有提供,可以根据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的资料请关注其它相关文章!