前言
最近很多项目上需要是调用其他系统的Webservice服务进行处理业务,第一次真正在项目中使用,感觉有些地方需要注意,故写下此文章(本文完全是个人运用理解,理解有误处请多多指正)
一、创建WebService服务
在添加Web服务后,VS将自动生成WebService服务类,且包含HelloWorld服务方法,用户可以在此处自定义服务方法,如添加AddFunction服务方法,标记方法属性标识为[WebMethod]
/// <summary> /// DianWebService 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class DianWebService : System.Web.Services.WebService { [WebMethod]//该属性标识为WebService服务方法 public string HelloWorld() { return "Hello World"; } [WebMethod] public int AddFunction(int a, int b) { return a + b; } }
二、调用WebService服务
在.NET平台下,存在两种方式调用WebService服务:一是直接在项目中添加服务引用;二是通过动态代理来调用服务。
方法一,项目中直接添加WebService服务引用(在项目菜单中选择“添加服务引用”)
说明:
区域1:Webservice服务的地址
区域2:设置Webservice服务的命名空间
区域3:针对该引入的服务做进一步的详细配置,包括服务的访问权限、是否异步等
说明:
区域1:定义引用的服务的访问权限,分为public和internal两种
区域2:确定引入的服务是否生成异步操作(此处暂时还没搞清能用于干什么)
区域3:配置web服务的高级配置,在此处配置后,才能够直接在项目中使用web服务类进行访问。否则无法直接访问服务中的接口方法。
特别需要注意:如果此处没有添加web引用,VS在创建web服务时,只会自动生成对应的服务协议接口(***Soap)和服务代理类(***SoapClient),其实我们可以通过接口查看到Webservice服务中的公开接口方法,以及通过服务代理类调用web服务接口方法。
比较明显的地方在于,未添加web引用时,VS自动创建的是服务引用(自动生成在Service References下),而添加引用后,vs创建的是web引用(自动成成在Web References下)。
(此处的***Soap和***SoapClient两个命名不太规范,哪位大拿能否指点下这两个专业术语如何称呼)
说明:
区域1:Webservice服务的地址
区域2:web服务的引用名(web服务的子命名空间)
区域3:操作添加web引用
//在项目中可以直接创建该WebService服务进行调用方法 WebService.DianWebService web = new WebService.DianWebService(); web.HelloWorld(); web.AddFunction(1, 2);
注意:调用Webservice服务的项目不能和提供Webservice服务的项目为同一个项目,否则会出现远程调用服务被关闭的异常,在测试代码时,可以使用一个项目调用另一个项目提供的服务(其中主要是方位不同地址或不同端口的Webservice服务就行)
方法二,通过动态代理来调用服务
先创建一个动态代理的服务,之后在项目中需要用到的地方直接根据传递不同参数调用不同的Webservice服务
public class Webservices { /// <summary< /// 实例化WebServices /// </summary< /// <param name="url"<WebServices地址</param< /// <param name="methodname"<调用的方法</param< /// <param name="args"<把webservices里需要的参数按顺序放到这个object[]里</param< public static object InvokeWebService(string namespaceName, string url, string methodname, object[] args) { //这里的namespace是需引用的webservices的命名空间,在这里是写死的,大家可以加一个参数从外面传进来。 if (string.IsNullOrEmpty(namespaceName)) namespaceName = "ServiceWebTest"; try { //获取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(url + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream); string classname = sd.Services[0].Name; ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(namespaceName); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodeProvider csc = new CSharpCodeProvider(); ICodeCompiler icc = csc.CreateCompiler(); //设定编译参数 CompilerParameters cplist = new CompilerParameters(); 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); if (true == cr.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.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(namespaceName + "." + classname, true, true); object obj = Activator.CreateInstance(t); System.Reflection.MethodInfo mi = t.GetMethod(methodname); return mi.Invoke(obj, args); } catch { return null; } } }
//在需要调用服务的地方调用 var objectUser = Webservices.InvokeWebService(namespaceName, url, methodname, new object[] { 1,2}); Response.Write(objectUser);