前言
最近很多項目上需要是調用其他系統的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);