1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Net;
6 using System.Xml;
7 using System.Collections.Specialized;
8 using EntityModel;
9 using CommonLibrary.Constant;
10 using System.Threading.Tasks;
11
12 namespace CommuService
13 {
14 /// <summary>
15 /// 服务访问类
16 /// </summary>
17 public class HttpHelper
18 {
19 private WebClient _client=null;
20 public HttpHelper(string contentType = "application/x-www-form-urlencoded",string encodingName="utf-8")
21 {
22 try
23 {
24 _client= CreateWebClient(contentType,encodingName);
25 }
26 catch(Exception ex)
27 {
28 throw ex;
29 }
30 }
31
32 private WebClient CreateWebClient(string contentType,string encodingName)
33 {
34 return new WebClient()
35 {
36 Encoding = Encoding.GetEncoding(encodingName),
37 Headers = ((Func<string,WebHeaderCollection>)
38 ((type)=>
39 {
40 var headers= new WebHeaderCollection();
41 headers.Add(HttpRequestHeader.ContentType,type);
42
43 return headers;
44 }
45 )).Invoke(contentType),
46 };
47 }
48
49 //public HttpResultInfo UploadValues(string url, NameValueCollection values, string currentType, string method = "POST")
50 /// <summary>
51 /// WebClient.UploadValuesvalue方法重新封装
52 /// 会阻塞当前调用“该方法”的线程
53 public HttpResultInfo UploadValues(string url, NameValueCollection values,string method = "POST")
54 {
55 try
56 {
57 if (_client != null)
58 {
59 byte[] result = _client.UploadValues(url, method, values);
60 string xml = _client.Encoding.GetString(result);
61 return this.CreateResultInfo(xml);
62 }
63 else
64 {
65 return null;
66 }
67 }
68 catch (Exception ex)
69 {
70 throw ex;
71 }
72 }
73
74 /// <summary>
75 /// WebClient 服务 异步请求方法封装,
76 /// 会创建新子线程来处理请求
77 /// </summary>
78 /// public async Task<HttpResultInfo> UploadValuesTaskAsync(string url, NameValueCollection values, string currentType, string method = "POST")
79 public async Task<HttpResultInfo> UploadValuesTaskAsync(string url, NameValueCollection values,string method = "POST")
80 {
81 try
82 {
83 Task<byte[]> taskResult = _client.UploadValuesTaskAsync(url, method, values);
84 byte[] result = await taskResult;
85 Func<byte[],Task<HttpResultInfo>> asynResultInfo = async (res) =>
86 {
87 await Task.Delay(TimeSpan.FromMilliseconds(100));
88 string xml = _client.Encoding.GetString(res);
89 return this.CreateResultInfo(xml);
90 };
91 return await asynResultInfo(result);
92 }
93 catch (Exception ex)
94 {
95 throw ex;
96 }
97 }
98 /// <summary>
99 /// WebClient 服务 异步请求方法封装,
100 /// 会创建新子线程来处理请求
101 /// </summary>
102 public async Task<HttpResultInfo> UploadDataTaskAsync(string url, byte[] bytes, string method = "POST")
103 {
104 try
105 {
106 Task<byte[]> taskResult = _client.UploadDataTaskAsync(url,method,bytes);
107 byte[] result = await taskResult;
108 Func<byte[], Task<HttpResultInfo>> asynResultInfo = async (res) =>
109 {
110 await Task.Delay(TimeSpan.FromMilliseconds(100));
111 string xml = _client.Encoding.GetString(res);
112 return this.CreateResultInfo(xml);
113 };
114 return await asynResultInfo(result);
115 }
116 catch (Exception ex)
117 {
118 throw ex;
119 }
120 }
121
122 //private HttpResultInfo CreateResultInfo(string xml, string currentType)
123 private HttpResultInfo CreateResultInfo(string xml)
124 {
125 HttpResultInfo httpResult = new HttpResultInfo() { Inform = new Inform() };
126 httpResult.XMLData = xml;
127 try
128 {
129 XmlDocument xmlDoc = new XmlDocument();
130 xmlDoc.LoadXml(xml);
131 XmlElement rootElement = xmlDoc.DocumentElement;
132 //首先校验XML文档根元素格式
133 if (VerifyRootElementFormat(rootElement))
134 {
135 //成功与失败,“返回结果”的XML文档结构不相同,
136 //但xml根节点必须包含result和message两个子节点
137 string result = rootElement.SelectSingleNode(XMLConst.Result).InnerText.Trim();
138 string message = rootElement.SelectSingleNode(XMLConst.Message).InnerText.Trim();
139 if (result == XMLConst.Failure)
140 {
141 httpResult.IsSuccess = false;
142 }
143 else if (result == XMLConst.Success)
144 {
145 //包括message元素有子节点和无子节点两种情况
146 httpResult.IsSuccess = true;
147 }
148 else
149 {
150 throw new Exception("XML交互文档的result节点内容不符合协议格式!");
151 }
152 //获得结果信息
153 httpResult.Inform.Result = result;
154 httpResult.Inform.Message = message;
155 //获得交互类型
156 httpResult.XMLInteractiveCode = rootElement.GetAttribute(XMLConst.Code).Trim();
157 return httpResult;
158 }
159 else
160 {
161 throw new Exception("XML交互文档的根元素不符合协议格式!");
162 }
163 }
164 catch (XmlException)
165 {
166 throw new Exception("服务端返回的XML格式错误,为:" + xml);
167 }
168 catch (System.Xml.XPath.XPathException exPath)
169 {
170 throw new Exception("服务端返回的XML节点错误," + exPath.Message);
171 }
172 catch (Exception ex)
173 {
174 throw ex;
175 }
176 }
177
178 /// <summary>
179 /// 验证交互文档的根元素语法格式(主要针对HTTP)
180 /// </summary>
181 private bool VerifyRootElementFormat(XmlElement rootElement)
182 {
183 //首先判断根节点
184 if (rootElement == null || rootElement.Name != XMLConst.Information
185 //|| !rootElement.HasAttribute(XMLConst.Code)
186 //|| String.IsNullOrEmpty(rootElement.GetAttribute(XMLConst.Code).Trim())
187 || rootElement.SelectSingleNode(XMLConst.Result) == null
188 || rootElement.SelectSingleNode(XMLConst.Message) == null)
189 {
190 return false;
191 }
192 else//若根节点无误,则进一步判断是否为http请求返回的XML
193 {
194 return true;
195 }
196 }
197
198 }
199
200 /// <summary>
201 /// 请求结果信息
202 /// </summary>
203 public class HttpResultInfo
204 {
205 public HttpResultInfo()
206 {
207 this.XMLData = string.Empty;
208 this.IsSuccess = false;
209 }
210
211 /// <summary>
212 /// 返回数据结果
213 /// </summary>
214 public string XMLData
215 {
216 get;
217 set;
218 }
219
220 /// <summary>
221 /// 请求是否成功
222 /// </summary>
223 public bool IsSuccess
224 {
225 get;
226 set;
227 }
228
229 /// <summary>
230 /// 该对象将被传递给完成异步操作时所调用的方法
231 /// 回调方法或完成事件的处理方法
232 /// </summary>
233 public object UserToken
234 {
235 get;
236 set;
237 }
238
239 /// <summary>
240 /// http服务请求响应的消息
241 /// </summary>
242 public Inform Inform
243 {
244 get;
245 set;
246 }
247
248 /// <summary>
249 /// XML交互代码
250 /// </summary>
251 public string XMLInteractiveCode
252 {
253 get;
254 set;
255 }
256 }
257 }