在Core環境下用WebRequest鏈接上遠程的web Api 實現數據的簡單CRUD(續)

這篇博客是上篇博客的續寫,上篇博客用的是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 }
UsersController.cs

感受HttpClient比WebRequest好用一點。畢竟都差很少吧,只不過是是現的方式不同,用法不同。又讓我體驗了一把反射的魅力。ide

這個是鏈接Web Api的git地址 https://github.com/1483523635/dotNetCoreAPIDemoTest函數

這個是用到的Web Api的git地址https://github.com/1483523635/dotNetCoreAPIDemo

相關文章
相關標籤/搜索