亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#WebService動態調用

2019-11-14 14:03:59
字體:
來源:轉載
供稿:網友

前言

  站在開發者的角度,WebService 技術確實是不再“時髦”。甚至很多人會說,我們不再用它。當然,為了使軟件可以更簡潔,更有層次,更易于實現緩存等機制,我是非常建議將 SOAP 轉為 RESTful 架構風格的。但到目前為止,WebService 在一些Public Institution 中使用還是十分廣泛的。

  這里主要討論一下關于WebService的調用問題。關于WebService 的調用分為靜態調用和動態調用兩種。

 

靜態調用

  靜態調用的方式是通過“Add Service Reference...”創建客戶端代理類。這種方式讓VS.NET環境來為我們生成服務代理,然后調用對應的Web服務。這樣是使工作簡單了,但是卻將提供Web服務的URL、方法名、參數綁定在一起了,這是VS.NET自動為我們生成Web服務代理的限制。如果發布Web服務的URL改變了,則我們需要重新讓VS.NET生成代理,并重新編譯。很常見的一個場景,某銀行Web服務,因為部署的URL更改,而不得不去重新編譯生成代理,這將會帶來很多不必要的工作量。如果我們使用動態調用就可以避免這種情況。關于靜態調用,不是這篇文章的重點,故不作詳細介紹。

 

動態調用

  在某些情況下我們需要在程序運行期間動態調用一個服務。在 .NET Framework 的 System.Web.Services.Description 命名空間中有我們需要的東西。動態調用有動態調用 WebService、生成客戶端代理程序集文件、生成客戶端代理類源代碼3種方式。

動態調用的具體步驟為:

1)從目標 URL 下載 WSDL 數據;

2)使用 ServiceDescription 創建和格式化 WSDL 文檔文件;

3)使用 ServiceDescriptionImporter 創建客戶端代理類;

4)使用 CodeDom 動態創建客戶端代理類程序集;

5)利用反射調用相關 WebService 方法。

  第一種方式通過在內存中創建動態程序集的方式完成了動態調用過程;第二種方式將客戶端代理類生成程序集文件保存到硬盤,然后可以通過 Assembly.LoadFrom() 載入并進行反射調用。對于需要多次調用的系統,要比每次生成動態程序集效率高出很多;第三種方式是保存源碼文件到硬盤中,然后再進行反射調用。

  這里將只討論第二種方式,這種方式也是我們在實際應用中最常用的。這種方式只下載 一次 WSDL 信息并創建代理類的程序集。往后程序每次啟動都會反射之前創建好的程序集。如果是 Web服務 URL 變更,只需要修改 App.config 中的 WebServiceUrl 和 PRoxyClassName 配置項,并將程序根目錄下生成的程序集刪除即可。下次程序啟動又會重新下載WSDL信息并創建代理類的程序集。 

  App.config文件。 

 1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3   <appSettings> 4     <!--WebService地址--> 5     <add key="WebServiceUrl" value="http://localhost:25060/testService/" /> 6     <!--WebService輸出dll文件名稱--> 7     <add key="OutputDllFilename" value="TestWebService.dll" /> 8     <!--WebService代理類名稱--> 9     <add key="ProxyClassName" value="TestService" />10   </appSettings>11 </configuration>

  

  創建代理類。 

  1     public class WSHelper  2     {  3         /// <summary>  4         /// 輸出的dll文件名稱  5         /// </summary>  6         private static string m_OutputDllFilename;  7   8         /// <summary>  9         /// WebService代理類名稱 10         /// </summary> 11         private static string m_ProxyClassName; 12  13         /// <summary> 14         /// WebService代理類實例 15         /// </summary> 16         private static object m_ObjInvoke; 17  18         /// <summary> 19         /// 接口方法字典 20         /// </summary> 21         private static Dictionary<EMethod, MethodInfo> m_MethodDic = new Dictionary<EMethod, MethodInfo>(); 22  23         /// <summary> 24         /// 創建WebService,生成客戶端代理程序集文件 25         /// </summary> 26         /// <param name="error">錯誤信息</param> 27         /// <returns>返回:true或false</returns> 28         public static bool CreateWebService(out string error) 29         { 30             try 31             { 32                 error = string.Empty; 33                 m_OutputDllFilename = ConfigurationManager.AppSettings["OutputDllFilename"]; 34                 m_ProxyClassName = ConfigurationManager.AppSettings["ProxyClassName"]; 35                 string webServiceUrl = ConfigurationManager.AppSettings["WebServiceUrl"]; 36                 webServiceUrl += "?WSDL"; 37  38                 // 如果程序集已存在,直接使用 39                 if (File.Exists(Path.Combine(Environment.CurrentDirectory, m_OutputDllFilename))) 40                 { 41                     BuildMethods(); 42                     return true; 43                 } 44  45                 //使用 WebClient 下載 WSDL 信息。 46                 WebClient web = new WebClient(); 47                 Stream stream = web.OpenRead(webServiceUrl); 48  49                 //創建和格式化 WSDL 文檔。 50                 if (stream != null) 51                 { 52                     // 格式化WSDL 53                     ServiceDescription description = ServiceDescription.Read(stream); 54  55                     // 創建客戶端代理類。 56                     ServiceDescriptionImporter importer = new ServiceDescriptionImporter 57                     { 58                         ProtocolName = "Soap", 59                         Style = ServiceDescriptionImportStyle.Client, 60                         CodeGenerationOptions = 61                             CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync 62                     }; 63  64                     // 添加 WSDL 文檔。 65                     importer.AddServiceDescription(description, null, null); 66  67                     //使用 CodeDom 編譯客戶端代理類。 68                     CodeNamespace nmspace = new CodeNamespace(); 69                     CodeCompileUnit unit = new CodeCompileUnit(); 70                     unit.Namespaces.Add(nmspace); 71  72                     ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); 73                     CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); 74  75                     CompilerParameters parameter = new CompilerParameters 76                     { 77                         GenerateExecutable = false, 78                         // 指定輸出dll文件名。 79                         OutputAssembly = m_OutputDllFilename 80                     }; 81  82                     parameter.ReferencedAssemblies.Add("System.dll"); 83                     parameter.ReferencedAssemblies.Add("System.XML.dll"); 84                     parameter.ReferencedAssemblies.Add("System.Web.Services.dll"); 85                     parameter.ReferencedAssemblies.Add("System.Data.dll"); 86  87                     // 編譯輸出程序集 88                     CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); 89  90                     // 使用 Reflection 調用 WebService。 91                     if (!result.Errors.HasErrors) 92                     { 93                         BuildMethods(); 94                         return true; 95                     } 96                     else 97                     { 98                         error = "反射生成dll文件時異常"; 99                     }100                     stream.Close();101                     stream.Dispose();102                 }103                 else104                 {105                     error = "打開WebServiceUrl失敗";106                 }107             }108             catch (Exception ex)109             {110                 error = ex.Message;111             }112             return false;113         }114 115         /// <summary>116         /// 反射構建Methods117         /// </summary>118         private static void BuildMethods()119         {120             Assembly asm = Assembly.LoadFrom(m_OutputDllFilename);121             //var types = asm.GetTypes();122             Type asmType = asm.GetType(m_ProxyClassName);123             m_ObjInvoke = Activator.CreateInstance(asmType);124 125             //var methods = asmType.GetMethods();126             var methods = Enum.GetNames(typeof(EMethod)).ToList();127             foreach (var item in methods)128             {129                 var methodInfo = asmType.GetMethod(item);130                 if (methodInfo != null)131                 {132                     var method = (EMethod)Enum.Parse(typeof(EMethod), item);133                     m_MethodDic.Add(method, methodInfo);134                 }135             }136         }137 138         /// <summary>139         /// 獲取請求響應140         /// </summary>141         /// <param name="method">方法</param>142         /// <param name="para">參數</param>143         /// <returns>返回:Json串</returns>144         public static string GetResponseString(EMethod method, params object[] para)145         {146             string result = null;147             if (m_MethodDic.ContainsKey(method))148             {149                 var temp = m_MethodDic[method].Invoke(m_ObjInvoke, para);150                 if (temp != null)151                 {152                     result = temp.ToString();153                 }154             }155             return result;156         }157     }

 

  調用接口。

1        // SOAP 請求響應方式2             TextBox3.Text = WSHelper.GetResponseString(EMethod.Add, Convert.ToInt32(TextBox1.Text), Convert.ToInt32(TextBox2.Text));

 

Http請求 

  除了靜態調用和動態調用,我們還可以發送HttpPost請求來調用WebService的方法。Soap請求就是HTTP POST的一個專用版本,遵循一種特殊的xml消息格式。使用HttpPost請求,對返回結果我們可以手動解析。下面的實現其實和調用WebAPI是完全一樣的。

  1     /// <summary>  2     /// 請求信息幫助  3     /// </summary>  4     public partial class HttpHelper  5     {  6         private static HttpHelper m_Helper;  7         /// <summary>  8         /// 單例  9         /// </summary> 10         public static HttpHelper Helper 11         { 12             get { return m_Helper ?? (m_Helper = new HttpHelper()); } 13         } 14  15         /// <summary> 16         /// 獲取請求的數據 17         /// </summary> 18         /// <param name="strUrl">請求地址</param> 19         /// <param name="requestMode">請求方式</param> 20         /// <param name="parameters">參數</param> 21         /// <param name="requestCoding">請求編碼</param> 22         /// <param name="responseCoding">響應編碼</param> 23         /// <param name="timeout">請求超時時間(毫秒)</param> 24         /// <returns>返回:請求成功響應信息,失敗返回null</returns> 25         public string GetResponseString(string strUrl, ERequestMode requestMode, Dictionary<string, string> parameters, Encoding requestCoding, Encoding responseCoding, int timeout = 300) 26         { 27             string url = VerifyUrl(strUrl); 28             HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url)); 29  30             HttpWebResponse webResponse = null; 31             switch (requestMode) 32             { 33                 case ERequestMode.Get: 34                     webResponse = GetRequest(webRequest, timeout); 35                     break; 36                 case ERequestMode.Post: 37                     webResponse = PostRequest(webRequest, parameters, timeout, requestCoding); 38                     break; 39             } 40  41             if (webResponse != null && webResponse.StatusCode == HttpStatusCode.OK) 42             { 43                 using (Stream newStream = webResponse.GetResponseStream()) 44                 { 45                     if (newStream != null) 46                         using (StreamReader reader = new StreamReader(newStream, responseCoding)) 47                         { 48                             string result = reader.ReadToEnd(); 49                             return result; 50                         } 51                 } 52             } 53             return null; 54         } 55  56  57         /// <summary> 58         /// get 請求指定地址返回響應數據 59         /// </summary> 60         /// <param name="webRequest">請求</param> 61         /// <param name="timeout">請求超時時間(毫秒)</param> 62         /// <returns>返回:響應信息</returns> 63         private HttpWebResponse GetRequest(HttpWebRequest webRequest, int timeout) 64         { 65             try 66             { 67                 webRequest.Accept = "text/html, application/xhtml+xml, application/json, text/javascript, */*; q=0.01"; 68                 webRequest.Headers.Add("Accept-Language", "zh-cn,en-US,en;q=0.5"); 69                 webRequest.Headers.Add("Cache-Control", "no-cache"); 70                 webRequest.UserAgent = "DefaultUserAgent"; 71                 webRequest.Timeout = timeout; 72                 webRequest.Method = "GET"; 73  74                 // 接收返回信息 75                 HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); 76                 return webResponse; 77             } 78             catch (Exception ex) 79             { 80                 return null; 81             } 82         } 83  84  85         /// <summary> 86         /// post 請求指定地址返回響應數據 87         /// </summary> 88         /// <param name="webRequest">請求</param> 89         /// <param name="parameters">傳入參數</param> 90         /// <param name="timeout">請求超時時間(毫秒)</param> 91         /// <param name="requestCoding">請求編碼</param> 92         /// <returns>返回:響應信息</returns> 93         private HttpWebResponse PostRequest(HttpWebRequest webRequest, Dictionary<string, string> parameters, int timeout, Encoding requestCoding) 94         { 95             try 96             { 97                 // 拼接參數 98                 string postStr = string.Empty; 99                 if (parameters != null)100                 {101                     parameters.All(o =>102                     {103                         if (string.IsNullOrEmpty(postStr))104                             postStr = string.Format("{0}={1}", o.Key, o.Value);105                         else106                             postStr += string.Format("&{0}={1}", o.Key, o.Value);107 108                         return true;109                     });110                 }111 112                 byte[] byteArray = requestCoding.GetBytes(postStr);113                 webRequest.Accept = "text/html, application/xhtml+xml, application/json, text/Javascript, */*; q=0.01";114                 webRequest.Headers.Add("Accept-Language", "zh-cn,en-US,en;q=0.5");115                 webRequest.Headers.Add("Cache-Control", "no-cache");116                 webRequest.UserAgent = "DefaultUserAgent";117                 webRequest.Timeout = timeout;118                 webRequest.ContentType = "application/x-www-form-urlencoded";119                 webRequest.ContentLength = byteArray.Length;120                 webRequest.Method = "POST";121 122                 // 將參數寫入流123                 using (Stream newStream = webRequest.GetRequestStream())124                 {125                     newStream.Write(byteArray, 0, byteArray.Length);126                     newStream.Close();127                 }128 129                 // 接收返回信息130                 HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();131                 return webResponse;132             }133             catch (Exception ex)134             {135                 return null;136             }137         }138 139 140         /// <summary>141         /// 驗證URL142         /// </summary>143         /// <param name="url">待驗證 URL</param>144         /// <returns></returns>145         private string VerifyUrl(string url)146         {147             if (string.IsNullOrEmpty(url))148                 throw new Exception("URL 地址不可以為空!");149 150             if (url.StartsWith("http://", StringComparison.CurrentCultureIgnoreCase))151                 return url;152 153             return string.Format("http://{0}", url);154         }155     }

 

  HttpPost 請求響應方式調用接口。

1             // Http Post 請求響應方式2             string url = m_WebServiceUrl + EMethod.Add.ToString();  //@"http://localhost:25060/testService.asmx/Add";3             Dictionary<string, string> parameters = new Dictionary<string, string> { { "parameter1", TextBox1.Text }, { "parameter2", TextBox2.Text } };4             string result = HttpHelper.Helper.GetResponseString(url, ERequestMode.Post, parameters, Encoding.Default, Encoding.UTF8);5             XElement root = XElement.Parse(result);6             TextBox3.Text = root.Value;

   

關于SOAP和REST

  我們都知道REST相比SOAP建議的標準更輕量級,甚到用Javascript都可以調用,使用方更方便、高效、簡單。但并不是說REST就是SOAP的替代者。他們都只是實現Web Service(web服務)的兩種不同的架構風格。就安全性等方面來說,SOAP還是更好的。

 

 

 源碼下載

 

 

擴展閱讀

http://www.ruanyifeng.com/blog/2011/09/restful

http://www.49028c.com/lema/archive/2012/02/23/2364365.html

http://stevenjohn.VEvb.com/blog/1442776

http://blog.linuxphp.org/archives/1505/

http://blog.csdn.net/superjj01/article/details/5270227

http://www.csdn.net/article/2013-06-13/2815744-RESTful-API

http://www.haodaima.net/art/2003909

http://my.oschina.net/lilw/blog/170518

 

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久99久久| 午夜伦理精品一区| 国产不卡av在线| 91av免费观看91av精品在线| 97在线免费观看视频| 精品无人区乱码1区2区3区在线| 狠狠色狠色综合曰曰| 亚洲成在人线av| 国产精品黄页免费高清在线观看| 欧美在线观看日本一区| 日韩av综合网| 日本国产一区二区三区| 日韩成人av一区| 欧美制服第一页| 日韩欧美999| 欧美日韩免费在线| 欧美激情亚洲国产| 国产999精品视频| 欧美一区二区.| 欧洲日本亚洲国产区| 久久国产精品影视| 精品久久久久久亚洲精品| 亚洲曰本av电影| 亚洲免费影视第一页| 亚洲国产高清福利视频| 日本欧美一级片| 欧美肥臀大乳一区二区免费视频| 欧日韩不卡在线视频| 91情侣偷在线精品国产| 欧美成年人视频网站欧美| 亚洲欧洲自拍偷拍| 欧美成人精品一区二区三区| 久久夜精品香蕉| 日韩精品视频中文在线观看| 久久精品视频导航| 91超碰中文字幕久久精品| 亚洲精品www| 色婷婷综合成人av| 色偷偷av一区二区三区| 中文字幕欧美精品日韩中文字幕| 国产精品久久久一区| 亚洲一区美女视频在线观看免费| 51精品国产黑色丝袜高跟鞋| 神马久久桃色视频| 国产综合在线观看视频| 日韩综合视频在线观看| 亚洲精品在线不卡| 欧美午夜性色大片在线观看| 91性高湖久久久久久久久_久久99| 亚洲欧洲午夜一线一品| 精品免费在线视频| 久久久久久久999| 另类视频在线观看| 国产视频精品va久久久久久| 国产精品福利无圣光在线一区| 91网站免费观看| 91日本在线观看| 亚洲毛茸茸少妇高潮呻吟| 91亚洲精品视频| 欧美激情aaaa| 亚洲成人网在线| 国产成人综合亚洲| 国产精品com| 91久久久久久久久久久| 日本一区二区三区在线播放| 国产精品欧美激情在线播放| 4444欧美成人kkkk| 欧美激情第一页xxx| 蜜月aⅴ免费一区二区三区| 国产精品a久久久久久| 国产精品免费久久久久影院| 国产精品九九久久久久久久| 久久综合伊人77777| 国产精品99久久久久久久久久久久| 亚洲国产成人精品一区二区| 91国在线精品国内播放| 亚洲天堂成人在线视频| 亚洲国产精品va| 国产91成人在在线播放| 国产成人aa精品一区在线播放| 俺去了亚洲欧美日韩| 国产精品69久久久久| 亚洲欧美在线看| 欧美尺度大的性做爰视频| 久久国产精品久久国产精品| 亚洲精品xxx| yellow中文字幕久久| 俺也去精品视频在线观看| 精品国内亚洲在观看18黄| 97香蕉久久夜色精品国产| 26uuu久久噜噜噜噜| 国产精品成av人在线视午夜片| 亚洲人精选亚洲人成在线| 欧美精品一区二区免费| 国产精品国内视频| 国产精品香蕉av| 欧美精品久久一区二区| 成人中文字幕+乱码+中文字幕| 亚洲国产91色在线| 91国在线精品国内播放| 欧美性高潮在线| 日本高清+成人网在线观看| 国产欧美在线播放| 午夜精品免费视频| 91国产中文字幕| 国产精品一区二区三区免费视频| 日韩免费看的电影电视剧大全| 欧美性高潮床叫视频| 精品国偷自产在线视频| 国产激情999| 久久精品男人天堂| 韩国三级电影久久久久久| 国产九九精品视频| 国产欧美欧洲在线观看| 一区二区欧美久久| 久久激情视频久久| 国产精品一区二区三区在线播放| 亚洲大胆美女视频| 国产精品∨欧美精品v日韩精品| 国产欧亚日韩视频| 欧美在线性视频| 伊人久久免费视频| 国产日韩在线看片| 97成人精品视频在线观看| 亚洲精品狠狠操| 国产精品久久久久久久久影视| 性色av香蕉一区二区| 色av中文字幕一区| 久久久999国产| 日本精品久久久久久久| 亚洲国产美女久久久久| 欧美做受高潮1| 久久亚洲成人精品| 亚洲精品免费一区二区三区| 欧美日韩国产页| www.欧美精品一二三区| 51精品在线观看| 欧美一区二区三区图| 日本道色综合久久影院| 欧美日韩激情小视频| 欧美成人在线免费视频| 国产aaa精品| 国产91精品高潮白浆喷水| 亚洲国产精品久久91精品| 国产精品久久久久久久久久久久久久| 国产精品自在线| 久久在线观看视频| 亚洲r级在线观看| 国产精品久久久久国产a级| 色综合久久久久久中文网| 2019中文字幕在线观看| 中文字幕欧美视频在线| 高清在线视频日韩欧美| 亚洲精品理论电影| 亚洲午夜久久久影院| 成人激情视频在线| 欧美激情久久久久久| 中文字幕精品久久| 色悠久久久久综合先锋影音下载| 96sao精品视频在线观看| 久久久久久久久久久网站| 亚洲男人天堂久| 国产日韩欧美在线观看| 欧美成人精品在线观看|