在Core环境下用WebRequest连接上远程的web Api 实现数据的简单CRUD(续)

这篇博客是上篇博客的续写,上篇博客用的是HttpClient取远程数据,用WebRequest提交,更新,删除数据。

今天进行了一下修改,全程用的都是HttpClient

说一下实现过程吧。

在实现的过程中,我发现了PostAsync和PutAsync需要的参数都是一个类型的,DeleteAsyc和GetAsync需要的参数都是一个类型的。那么这就省很多事了只用一个方法+反射,里边再加一个if{...}else{...}就可解决四个问题了。

主要就是添加了HandleDataFactoryAsync这个方法里边注释写的很详细。

 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         }

修改用法

        /// <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的方法,别的都没有改变。

这是整个类

  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好用一点。毕竟都差不多吧,只不过是是现的方式不一样,用法不一样。又让我体验了一把反射的魅力。

这个是连接Web Api的git地址 https://github.com/1483523635/dotNetCoreAPIDemoTest

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

posted @ 2017-05-07 19:01  Bluto  阅读(1446)  评论(0编辑  收藏  举报