龙空技术网

C# 动态调用WebService

中年农码工 3919

前言:

现时各位老铁们对“jswebservice调用”大致比较关注,我们都需要知道一些“jswebservice调用”的相关文章。那么小编同时在网络上搜集了一些有关“jswebservice调用””的相关内容,希望朋友们能喜欢,朋友们一起来了解一下吧!

一、前言

在工作中要切换多个环境的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=";/>

<!--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];

}

标签: #jswebservice调用 #soapui调用webservice接口参数为args