C#: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="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>
如何生成webservice客户端///<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];
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论