因為項目中需要實現客戶端與服務器端的數據交換,以及獲取服務器端其他程序的分析結果,所以對WebService做了些簡單的了解,現記錄如下:
一、WebService程序編寫
1、 在VS中新建空白網站
2、 在空白網站中添加新建項,選擇“web服務”
3、 在web服務中寫入需要向客服端提供的接口函數,我這里簡單的寫兩個讀取服務器中某個txt文檔的內容並返回的函數。
1 [WebService(Namespace = "http://tempuri.org/")] 2 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 3 [System.ComponentModel.ToolboxItem(false)] 4 // 若要允許使用 ASP.NET AJAX 從腳本中調用此 Web 服務,請取消對下行的注釋。 5 // [System.Web.Script.Services.ScriptService] 6 public class Project3DInfoService : System.Web.Services.WebService 7 { 8 9 [WebMethod(Description = "模糊匹配")] 10 public string getProjectBaseInfoFuzzyQuery(string prjName) 11 { 12 string txtFileName = @"D:\NJ3DGIS\JsonStrs.txt"; 13 string JsonStr = File.ReadAllText(txtFileName, Encoding.Default); 14 return JsonStr; 15 } 16 17 [WebMethod(Description = "精確匹配")] 18 public string getProjectBaseInfo(string prjName) 19 { 20 string txtFileName = @"D:\NJ3DGIS\JsonStr.txt"; 21 string JsonStr = File.ReadAllText(txtFileName, Encoding.Default); 22 return JsonStr; 23 } 24 }
二、WebService發布這里以最簡單常用的IIS發布為例
1、 打開IIS管理器,右擊[應用池],添加應用程序池,注意選擇.NET Framework版本。也可以直接使用現有的應用程序池。
2、 右擊現有的網站,選擇添加應用程序,設置應用程序的物理路徑為WebService程序所在的文件夾,文件目錄選到asmx文件所在文件夾一級。並設置其他參數。
3、 設置完成后右擊新添加的應用程序—[管理應用程序]—[瀏覽]即可看到你寫的函數,還可以輸入參數查看返回結果。
注:如果瀏覽器顯示HTTP 錯誤 403.14 – Forbidden,可在IIS管理器功能視圖界面,選擇進入[目錄瀏覽],在最右邊面板上點擊[啟動]。
三、客服端調用WebService
客服端可以跨語言調用WebService,調用方法有多種。
1、 添加服務引用
«右擊項目程序[引用]—添加服務引用。在彈出的窗體界面中選擇[高級]—[添加web引用],在URL一欄中輸入WebService地址(就是[瀏覽]時瀏覽器顯示的地址,把locahost改成服務器IP:端口號),點擊[添加引用]完成添加;
添加服務引用后
«添加服務引用后就可直接調用WebService提供的接口函數了。但為了使程序具有可移植性,我們可以將WebService引用地址寫在配置文件中,將服務引用的URL設置從配置文件中的讀取值。具體做法就是修改Reference.cs(可在本地文件中找到,或者在服務的類名上按F12進入)代碼中的”this.URL= “的值設為從配置文件中讀取。這樣當服務器IP有變動或者需要部署到其他地方時只要修改配置文件中的相應URL值即可。
這種方法最簡單,但明顯實用性不高。
2、 WebService打包
«WebService封裝生成dll可參照這篇博客
http://blog.csdn.net/gxxloveszj/article/details/8332584
«WebService封裝后可以直接添加該dll調用接口函數,不需要添加服務引用,但每次服務器有改動都需要重新封裝一次。
3、 動態調用web服務
動態調用web服務只需要WebService編寫方提供web服務URL和函數名,這個涉及到一些反射、CodeDom、編程使用C#編譯器知識,說起來麻煩但使用起來很簡單,詳情可參考博客
http://www.cnblogs.com/chenmfly/p/4463422.html
代碼如下,其中,url是Web服務的地址,methodname是要調用服務方法名,args是要調用Web服務所需的參數,返回值就是web服務返回的結果了
public static object InvokeWebService(string url, string methodname, object[] args) { return InvokeWebServiceMy(url, null, methodname, args); } public static object InvokeWebServiceMy(string url, string classname, string methodname, object[] args) { string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; if ((classname == null) || (classname == "")) { classname = GetWsClassName(url); } try { //獲取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(url + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(@namespace); //生成客戶端代理類代碼; 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(@namespace + "." + classname, true, true); object obj = Activator.CreateInstance(t); System.Reflection.MethodInfo mi = t.GetMethod(methodname); return mi.Invoke(obj, args); } catch (Exception ex) { throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace)); } } private static string GetWsClassName(string wsUrl) { string[] parts = wsUrl.Split('/'); string[] pps = parts[parts.Length - 1].Split('.'); return pps[0]; }
另外還可以使用HttpWebRequest等方法來動態調用web服務,網上也有不少詳細資料,這里就不貼了。