1. 程式人生 > >標準webservice調用

標準webservice調用

amp org OS post valid context urn 取消 sip

現代定義的webservice一般都傾向於restfull風格的http請求,但工作中還是會遇到前輩們寫的時代代碼。

我們更傾向於封裝代碼來調用,而不是服務引用。請看:

Service.asmx服務的註解

1     [WebService(Namespace = "http://shanghai.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 Service : System.Web.Services.WebService 7 {}

Web.config配置文件重要節點

 1   <system.web>
 2     <httpRuntime requestValidationType="Service.RequestValidatorDisabled" />
 3     <webServices>
 4       <protocols>
 5
<add name="HttpPost"/> 6 <add name="HttpGet"/> 7 </protocols> 8 </webServices> 9 <compilation debug="true" targetFramework="4.0"/> 10 </system.web> 11 12 <system.webServer> 13 <defaultDocument> 14 <files> 15
<add value="Service.asmx"/> 16 </files> 17 </defaultDocument> 18 </system.webServer>
1     public class RequestValidatorDisabled : System.Web.Util.RequestValidator
2     {
3         protected override bool IsValidRequestString(System.Web.HttpContext context, string value, System.Web.Util.RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
4         {
5 
6             validationFailureIndex = -1;
7             return true;
8         }
9     }

以上不加驗證也可。

客戶端調用工具

        public static string Serialize<T>(T entity, bool base64 = true)
        {
            using (System.IO.StringWriter sw = new System.IO.StringWriter())
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                serializer.Serialize(sw, entity);

                if (base64)
                {
                    return Convert.ToBase64String(Encoding.UTF8.GetBytes(sw.ToString()));
                }
                else
                {
                    return sw.ToString();
                }
            }
        }

        public static T Deserialize<T>(string data, bool base64 = true)
        {
            var xml = "";
            if (base64)
            {
                xml = Encoding.UTF8.GetString(Convert.FromBase64String(data.Replace(" ", "+")));
            }
            else
            {
                xml = data;
            }

            using (System.IO.StringReader sr = new System.IO.StringReader(xml))
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(T));
                return (T)deserializer.Deserialize(sr);
            }
        }

請求方法(去掉服務器返回的服務的命名空間),都以POST方式提交

 1         public static T Post<T>(string url, Dictionary<string, string> kvs)
 2         {
 3             var data = "";
 4             foreach (var k in kvs.Keys)
 5             {
 6                 if (string.IsNullOrEmpty(data))
 7                 {
 8                     data += k + "=" + kvs[k];
 9                 }
10                 else
11                 {
12                     data += "&" + k + "=" + kvs[k];
13                 }
14             }
15 
16             HttpWebRequest rq = null;
17 
18             try
19             {
20                 rq = WebRequest.Create(url) as HttpWebRequest;
21             }
22             catch (Exception) { throw new Exception("錯誤:WEBSERVICE地址無效"); }
23 
24             rq.Method = "POST";
25             rq.ContentType = "application/x-www-form-urlencoded";
26 
27             byte[] bs = Encoding.UTF8.GetBytes(data);
28             rq.ContentLength = bs.Length;
29             try
30             {
31                 using (Stream writer = rq.GetRequestStream())
32                 {
33                     if (bs.Length > 0)
34                     {
35                         writer.Write(bs, 0, bs.Length);
36                     }
37                 }
38             }
39             catch (Exception) { throw new Exception("錯誤:發送失敗,網絡異常"); }
40 
41             var response = "";
42             try
43             {
44                 var rp = rq.GetResponse() as HttpWebResponse;
45 
46                 using (Stream reader = rp.GetResponseStream())
47                 {
48                     response = new StreamReader(reader, Encoding.UTF8).ReadToEnd();
49                 }
50             }
51             catch (Exception err) { throw new Exception("錯誤:接收失敗,網絡異常"); }
52 
53             try
54             {
55                 return Deserialize<T>(TrimXmlns(response), false);
56             }
57             catch (Exception err) { throw new Exception("錯誤:數據序列化異常"); }
58         }
59 
60         private static string TrimXmlns(string source)
61         {
62             return source.Replace("xmlns=\"http://shanghai.org/\"", "");
63         }

服務端定義接口

 1         [WebMethod(Description = "導入Excel移庫計劃")]
 2         public TransExcelDto ImportTransExcel(string data)
 3         {
 4             try
 5             {
 6                 var tf = Common.Utilities.Deserialize<TransExcelDto>(data);
 7 
 8                 return DataAccess.ImportTransExcel(tf);
 9             }
10             catch (Exception e)
11             {
12                 return new TransExcelDto().Failure(98, e.Message) as TransExcelDto;
13             }
14         }

調用舉例,註意下面的key = data,即使接口的參數

1 TransExcelDto request = new TransExcelDto() { SessionId = Cache.SessionId };
2 3 
4 var postData = new Dictionary<string, string>();
5 postData.Add("data", Common.Utilities.Serialize<TransExcelDto>(request));
6 
7 TransExcelDto result = Common.Utilities.Post<TransExcelDto>(Metadata.WebServiceUrl + "/ImportTransExcel", postData);

標準webservice調用