這篇博客是上篇博客的續寫,上篇博客用的是HttpClient取遠程數據,用WebRequest提交,更新,刪除數據。git
今天進行了一下修改,全程用的都是HttpClientgithub
說一下實現過程吧。web
在實現的過程當中,我發現了PostAsync和PutAsync須要的參數都是一個類型的,DeleteAsyc和GetAsync須要的參數都是一個類型的。那麼這就省不少事了只用一個方法+反射,裏邊再加一個if{...}else{...}就可解決四個問題了。數據庫
主要就是添加了HandleDataFactoryAsync這個方法裏邊註釋寫的很詳細。json
1 /// <summary> 2 /// 這是用HttpClient調用Web Api實現CRUD到數據庫中 3 /// </summary> 4 /// <param name="u">數據</param> 5 /// <param name="url">請求的url</param> 6 /// <param name="RequestType">請求的類型</param> 7 /// <returns></returns> 8 private async Task<string> HandleDataFactoryAsync(Users u, string url, string RequestType) 9 { 10 //聲明一個HttpClient類 11 HttpClient client = new HttpClient(); 12 //將Users轉化爲JSon字符串 13 string jsonString = UsersConvertToJson(u); 14 //聲明一個String類型的Context在提交數據時須要用到這個參數 15 var context = new StringContent(jsonString, Encoding.UTF8, "application/json"); 16 //設置反射須要獲取的方法名稱 17 string method = RequestType + "Async"; 18 19 //我這裏將兩步寫在了一塊兒 20 //1.經過獲取全部的方法 21 //2.經過linq語句查詢我須要的方法 22 //固然也能夠直接GetMethod(MethodName) 23 //我感受那樣的話可能會拋「方法找不到」的異常 24 //我用Linq查詢避免了 25 MethodInfo info = client.GetType().GetMethods().FirstOrDefault(m => m.Name == method); 26 if (info != null) 27 { 28 HttpResponseMessage result; 29 30 //因爲put和post須要的參數類型和數目一致因此放在一塊處理了 31 //get和delete也同樣 32 if (method == "PutAsync" || method == "PostAsync") 33 { 34 //激活這個方法而且傳遞所須要的參數 35 result= await (Task<HttpResponseMessage>)info.Invoke(client, new Object[] { url, context }); 36 } 37 else 38 { 39 result = await (Task<HttpResponseMessage>)info.Invoke(client, new Object[] { url }); 40 } 41 //將響應內容返回 42 return await result.Content.ReadAsStringAsync(); 43 44 } 45 46 return ""; 47 48 }
修改用法api
/// <summary> /// 傳遞數據到遠程API的數據庫中 /// </summary> /// <param name="u"></param> /// <returns></returns> private async Task<string> CreateAsync(Users u) { string url = baseURL; string requestMethod = "Post"; //return await HandleDataAsync(u, url, requestMethod); return await HandleDataFactoryAsync(u, url, requestMethod); } private async Task<string> UpdateAsync(Users u) { string url = baseURL + @"/" + u.ID; string requestMethod = "Put"; // return await HandleDataAsync(u, url, requestMethod); return await HandleDataFactoryAsync(u, url, requestMethod); } private async Task<string> DeleteAsync(Users u) { string url = baseURL + @"/" + u.ID; string requestMethod = "Delete"; //return await HandleDataAsync(u, url, requestMethod); return await HandleDataFactoryAsync(u, url, requestMethod); }
註釋掉的那行是原來調用WebRequest的方法,別的都沒有改變。app
這是整個類async
1 using Microsoft.AspNetCore.Mvc; 2 using Newtonsoft.Json; 3 using Newtonsoft.Json.Linq; 4 using System; 5 using System.Collections.Generic; 6 using System.IO; 7 using System.Linq; 8 using System.Net; 9 using System.Net.Http; 10 using System.Reflection; 11 using System.Text; 12 using System.Threading.Tasks; 13 using TestAPI.Models; 14 15 namespace TestAPI.Controllers 16 { 17 public class UsersController : Controller 18 { 19 #region 成員變量 20 //這個baseURL是個人webApi的地址 21 private static string baseURL = "http://localhost:56853/api/users"; 22 //用於存放全部的用戶 23 private static IList<Users> _context; 24 25 #endregion 26 27 #region 構造函數 28 public UsersController() 29 { 30 //實例化對象 31 _context = new List<Users>(); 32 //獲取全部的用戶的信息 33 _context = GetAllUserList(); 34 35 } 36 37 #endregion 38 39 #region 類內方法 40 41 /// <summary> 42 /// 經過api獲取全部的用戶的信息 43 /// </summary> 44 /// <returns>JSON String</returns> 45 private string GetALLUserInfoFromAPI() 46 { 47 HttpClient client = new HttpClient(); 48 var con = client.GetStringAsync(baseURL); 49 return con.Result; 50 51 } 52 53 private string UsersConvertToJson(Users u) 54 { 55 return JsonConvert.SerializeObject(u); 56 } 57 /// <summary> 58 /// 傳遞數據到遠程API的數據庫中 59 /// </summary> 60 /// <param name="u"></param> 61 /// <returns></returns> 62 private async Task<string> CreateAsync(Users u) 63 { 64 string url = baseURL; 65 string requestMethod = "Post"; 66 //return await HandleDataAsync(u, url, requestMethod); 67 return await HandleDataFactoryAsync(u, url, requestMethod); 68 } 69 70 private async Task<string> UpdateAsync(Users u) 71 { 72 string url = baseURL + @"/" + u.ID; 73 string requestMethod = "Put"; 74 // return await HandleDataAsync(u, url, requestMethod); 75 return await HandleDataFactoryAsync(u, url, requestMethod); 76 } 77 private async Task<string> DeleteAsync(Users u) 78 { 79 string url = baseURL + @"/" + u.ID; 80 string requestMethod = "Delete"; 81 //return await HandleDataAsync(u, url, requestMethod); 82 return await HandleDataFactoryAsync(u, url, requestMethod); 83 84 } 85 private bool UsersExist(int iD) 86 { 87 return _context.Any(u => u.ID == iD); 88 } 89 /// <summary> 90 /// 用WebRequest處理數據 91 /// </summary> 92 /// <param name="Data">User實體類</param> 93 /// <param name="Url">遠程API的URL</param> 94 /// <param name="RequestMethod">請求的方法</param> 95 /// <returns></returns> 96 private async Task<string> HandleDataAsync(Users Data, string Url, string RequestMethod) 97 { 98 string UsersJson = UsersConvertToJson(Data); 99 var request = WebRequest.CreateHttp(Url); 100 request.Accept = "application/json"; 101 //下邊這行不設置會出現沒法識別mediaType 415 這個錯誤 102 request.ContentType = "application/json"; 103 request.Method = RequestMethod; 104 //向request提交數據 105 using (StreamWriter writer = new StreamWriter(await request.GetRequestStreamAsync())) 106 { 107 writer.Write(UsersJson); 108 } 109 //獲取響應 110 var reponse = await request.GetResponseAsync(); 111 //返回響應數據 112 using (StreamReader reader = new StreamReader(reponse.GetResponseStream())) 113 { 114 return reader.ReadToEnd(); 115 } 116 } 117 118 /// <summary> 119 /// 這是用HttpClient調用Web Api實現CRUD到數據庫中 120 /// </summary> 121 /// <param name="u">數據</param> 122 /// <param name="url">請求的url</param> 123 /// <param name="RequestType">請求的類型</param> 124 /// <returns></returns> 125 private async Task<string> HandleDataFactoryAsync(Users u, string url, string RequestType) 126 { 127 //聲明一個HttpClient類 128 HttpClient client = new HttpClient(); 129 //將Users轉化爲JSon字符串 130 string jsonString = UsersConvertToJson(u); 131 //聲明一個String類型的Context在提交數據時須要用到這個參數 132 var context = new StringContent(jsonString, Encoding.UTF8, "application/json"); 133 //設置反射須要獲取的方法名稱 134 string method = RequestType + "Async"; 135 136 //我這裏將兩步寫在了一塊兒 137 //1.經過獲取全部的方法 138 //2.經過linq語句查詢我須要的方法 139 //固然也能夠直接GetMethod(MethodName) 140 //我感受那樣的話可能會拋「方法找不到」的異常 141 //我用Linq查詢避免了 142 MethodInfo info = client.GetType().GetMethods().FirstOrDefault(m => m.Name == method); 143 if (info != null) 144 { 145 HttpResponseMessage result; 146 147 //因爲put和post須要的參數類型和數目一致因此放在一塊處理了 148 //get和delete也同樣 149 if (method == "PutAsync" || method == "PostAsync") 150 { 151 //激活這個方法而且傳遞所須要的參數 152 result= await (Task<HttpResponseMessage>)info.Invoke(client, new Object[] { url, context }); 153 } 154 else 155 { 156 result = await (Task<HttpResponseMessage>)info.Invoke(client, new Object[] { url }); 157 } 158 //將響應內容返回 159 return await result.Content.ReadAsStringAsync(); 160 161 } 162 163 return ""; 164 165 } 166 /// <summary> 167 /// 獲取全部用戶的List 168 /// </summary> 169 private IList<Users> GetAllUserList() 170 { 171 IList<Users> userslist = new List<Users>(); 172 var JsonString = GetALLUserInfoFromAPI(); 173 JArray UsersArray = JArray.Parse(JsonString); 174 for (int i = 0; i < UsersArray.Count; i++) 175 { 176 userslist.Add(StringConvertToUser(UsersArray[i].ToString())); 177 } 178 return userslist; 179 } 180 /// <summary> 181 /// 將Json對象的字符串轉化爲users對象 182 /// </summary> 183 /// <param name="JsonString">json對象的字符串</param> 184 /// <returns>Users對象</returns> 185 private Users StringConvertToUser(string JsonString) 186 { 187 return JsonConvert.DeserializeObject<Users>(JsonString); 188 } 189 #endregion 190 191 #region Index 192 // GET: Users 193 public async Task<IActionResult> Index() 194 { 195 return View(_context); 196 } 197 198 199 200 #endregion 201 202 #region Details 203 204 // GET: Users/Details/5 205 public async Task<IActionResult> Details(int? id) 206 { 207 if (id == null) 208 { 209 return BadRequest(); 210 } 211 var users = _context.FirstOrDefault(u => u.ID == id); 212 if (users == null) 213 { 214 return NotFound(); 215 } 216 return View(users); 217 } 218 219 #endregion 220 221 #region Create 222 223 // GET: Users/Create 224 public IActionResult Create() 225 { 226 return View(); 227 } 228 229 // POST: Users/Create 230 // To protect from overposting attacks, please enable the specific properties you want to bind to, for 231 // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 232 [HttpPost] 233 [ValidateAntiForgeryToken] 234 public async Task<IActionResult> Create([Bind("ID,name,pwd")] Users users) 235 { 236 if (ModelState.IsValid) 237 { 238 239 await CreateAsync(users); 240 return RedirectToAction("Index"); 241 } 242 return View(); 243 } 244 245 #endregion 246 247 #region Edit 248 249 // GET: Users/Edit/5 250 public async Task<IActionResult> Edit(int? id) 251 { 252 if (id == null) 253 { 254 return BadRequest(); 255 } 256 var users = _context.FirstOrDefault(u => u.ID == id); 257 if (users == null) 258 { 259 return NotFound(); 260 } 261 return View(users); 262 } 263 264 // POST: Users/Edit/5 265 // To protect from overposting attacks, please enable the specific properties you want to bind to, for 266 // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 267 [HttpPost] 268 [ValidateAntiForgeryToken] 269 public async Task<IActionResult> Edit(int id, [Bind("ID,name,pwd")] Users users) 270 { 271 272 if (ModelState.IsValid) 273 { 274 if (id != users.ID) 275 { 276 return BadRequest(); 277 } 278 try 279 { 280 await UpdateAsync(users); 281 return RedirectToAction("Index"); 282 } 283 catch 284 { 285 if (UsersExist(users.ID)) 286 { 287 return NotFound(); 288 } 289 throw; 290 } 291 292 } 293 return View(); 294 } 295 296 297 #endregion 298 299 #region Delete 300 301 302 // GET: Users/Delete/5 303 public async Task<IActionResult> Delete(int? id) 304 { 305 if (id == null) 306 { 307 return BadRequest(); 308 } 309 var users = _context.FirstOrDefault(u => u.ID == id); 310 if (users == null) 311 { 312 return NotFound(); 313 } 314 315 return View(users); 316 } 317 318 // POST: Users/Delete/5 319 [HttpPost, ActionName("Delete")] 320 [ValidateAntiForgeryToken] 321 public async Task<IActionResult> DeleteConfirmed(int id) 322 { 323 var users = _context.SingleOrDefault(u => u.ID == id); 324 await DeleteAsync(users); 325 return RedirectToAction("Index"); 326 } 327 #endregion 328 329 } 330 }
感受HttpClient比WebRequest好用一點。畢竟都差很少吧,只不過是是現的方式不同,用法不同。又讓我體驗了一把反射的魅力。ide
這個是鏈接Web Api的git地址 https://github.com/1483523635/dotNetCoreAPIDemoTest函數
這個是用到的Web Api的git地址https://github.com/1483523635/dotNetCoreAPIDemo