通过HTTP请求WEBAPI的方式
Posted Henry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过HTTP请求WEBAPI的方式相关的知识,希望对你有一定的参考价值。
平时工作中长期需要用到通过HTTP调用API进行数据获取以及文件上传下载(C#,JAVA...都会用到)。这里获取的是包括网页的所有信息。如果单纯需要某些数据内容。可以自己构造函数甄别抠除出来!一般的做法是根据源码的格式,用正则来过滤出你需要的内容部分。
C#中的调用:
方式一:webclient和httpclient
方式二:WebRequest和webresponse
方式三:通过js 直接访问api接口,页面通过jquery调用
方式四:WebBrowser
1.webclient和httpclient
实例①
#region webclient应用 #region Controllers MyImageServerEntities db = new MyImageServerEntities(); public ActionResult Index() { return View(); } public ActionResult FileUpload() { HttpPostedFileBase file = Request.Files["fileUp"]; string fileName = Path.GetFileName(file.FileName); string fileExt = Path.GetExtension(fileName); if (fileExt == ".jpg") { var list = db.ImageServerInfo.Where<ImageServerInfo>(u => u.FlgUsable == true).ToList();//找出可用的图片服务器. int count = list.Count(); Random random = new Random(); int r = random.Next(); int i = r % count; string serverUrl = list[i].ServerUrl; int serverId = list[i].ServerId; string url = "http://" + serverUrl + "/FileUp.ashx?serverId=" + serverId + "&fileExt=" + fileExt; WebClient webClient = new WebClient(); webClient.UploadData(url, StreamToBytes(file.InputStream)); } return Content("ok"); } public ActionResult ShowImage() { var list = db.ImageServerInfo.Where<ImageServerInfo>(c => c.FlgUsable == true).ToList(); ViewData["imageServerList"] = list; return View(); } private byte[] StreamToBytes(Stream stream) { byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); stream.Seek(0, SeekOrigin.Begin); return buffer; } #endregion #region Model context.Response.ContentType = "text/plain"; int serverId = int.Parse(context.Request["serverId"]); string fileExt = context.Request["fileExt"]; string dir = "/ImagePath/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/"; Directory.CreateDirectory(Path.GetDirectoryName(context.Request.MapPath(dir))); string newfileName = Guid.NewGuid().ToString(); string fullDir = dir + newfileName + fileExt; using (FileStream fileStream = File.Open(context.Request.MapPath(fullDir), FileMode.OpenOrCreate)) { context.Request.InputStream.CopyTo(fileStream); MyImageServerEntities db = new MyImageServerEntities(); ImageInfo imageInfo = new ImageInfo(); imageInfo.ImageName = fullDir; imageInfo.ImageServerId = serverId; db.ImageInfo.Add(imageInfo); db.SaveChanges(); } #endregion #endregion #region httpclient 创建并初始化对象: client.BaseAddress = new Uri(url); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 读集合: HttpResponseMessage response = client.GetAsync(url).Result; var userList = response.Content.ReadAsAsync<IEnumerable<数据类型>>().Result; 根据编号读对象 HttpResponseMessage response1 = client.GetAsync(url).Result; var userInfo = response1.Content.ReadAsAsync<数据类型>().Result; 增加: HttpResponseMessage response = client.PostAsJsonAsync("api/userinfo", userInfo).Result; 使用response.IsSuccessStatusCode判断是否成功 使用response.Content.ToString()获取返回值 修改: HttpResponseMessage response = client.PutAsJsonAsync("api/userinfo/" + userInfo.UserId, userInfo).Result; 使用response.IsSuccessStatusCode判断是否成功 使用response.Content.ToString()获取返回值 删除: HttpResponseMessage response = client.DeleteAsync("api/userinfo/" + uid).Result; 使用response.IsSuccessStatusCode判断是否成功 使用response.Content.ToString()获取返回值 #endregion
实例②
WebClient获取网页数据: //using System.IO; try { WebClient webClient = new WebClient(); webClient.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于向Internet资源的请求进行身份验证的网络凭据 Byte[] pageData = webClient.DownloadData("http://www.360doc.com/content/11/0427/03/1947337_112596569.shtml"); //string pageHtml = Encoding.Default.GetString(pageData); //如果获取网站页面采用的是GB2312,则使用这句 string pageHtml = Encoding.UTF8.GetString(pageData); //如果获取网站页面采用的是UTF-8,则使用这句 using (StreamWriter sw = new StreamWriter("e:\\\\ouput.txt"))//将获取的内容写入文本 { htm = sw.ToString();//测试StreamWriter流的输出状态,非必须 sw.Write(pageHtml); } } catch (WebException webEx) { Console.W } 如果为了实际项目的效率考虑,需要考虑在函数中分配一个内存区域。大概写法如下: //MemoryStream是一个支持储存区为内存的流。 byte[] buffer = new byte[1024]; using (MemoryStream memory = new MemoryStream()) { int index = 1, sum = 0; while (index * sum < 100 * 1024) { index = reader.Read(buffer, 0, 1024); if (index > 0) { memory.Write(buffer, 0, index); sum += index; } } //网页通常使用utf-8或gb2412进行编码 Encoding.GetEncoding("gb2312").GetString(memory.ToArray()); if (string.IsNullOrEmpty(html)) { return html; } else { Regex re = new Regex(@"charset=(? charset[/s/S]*?)[ |\']"); Match m = re.Match(html.ToLower()); encoding = m.Groups[charset].ToString(); } if (string.IsNullOrEmpty(encoding) || string.Equals(encoding.ToLower(), "gb2312")) { return html; } }
实例③
使用WebClient进行文件下载,这里使用了Task异步方式,也可以改为普通方法或静态方法: /// <summary> /// 下载文件 /// </summary> /// <param name="fileUrl">文件地址</param> /// <param name="filePath">文件的本地路径</param> /// <returns>文件在本地的存储路径</returns> private Task GetFileLocalPath(string fileUrl, string filePath) { return Task.Run(() => { try { using (var mc = new WebClient()) { mc.DownloadFile(new Uri(fileUrl), filePath); } } catch (Exception ex) { LogHelper.WriteErrorLog("下载文件时出现异常。", ex); } }); } /// <summary> /// 下载文件 /// </summary> /// <param name="fileUrl">文件地址</param> /// <param name="filePath">文件的本地路径</param> /// <returns>文件在本地的存储路径</returns> private Task DownloadFile(string fileUrl, string filePath) { return Task.Run(() => { try { using (var webClient = new WebClient()) { var netStream = webClient.OpenRead(fileUrl); if (netStream != null) { FileStream fstr = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write); byte[] readbyte = new byte[102400]; int realReadLen = netStream.Read(readbyte, 0, readbyte.Length); while (realReadLen > 0) { fstr.Write(readbyte, 0, realReadLen); realReadLen = netStream.Read(readbyte, 0, readbyte.Length); Thread.Sleep(10); } netStream.Dispose(); fstr.Flush(); fstr.Close(); } } } catch (Exception ex) { LogHelper.WriteErrorLog("下载文件时出现异常。", ex); } }); } HttpClient,这个类提供的都是异步方法,下面包含了POST、GET、PUT、DELETE四个方法,还有一个SEND方法稍加改动即可实现: public static async void AsyncPost(string url, string body, Action<RequestResult> callback, int timeoutSeconds = 10) { var requestResult = new RequestResult(); if (!IsConnectedInternet()) { requestResult.Message = "网络连接错误,请稍后再试。"; callback?.Invoke(requestResult); return; } try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6"); client.Timeout = new TimeSpan(0, 0, timeoutSeconds); //byte[] requestBody = Encoding.UTF8.GetBytes(body); HttpContent content = new StringContent(body); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var response = await client.PostAsync(url, content); //确保HTTP成功状态值 response.EnsureSuccessStatusCode(); //await异步读取最后的JSON await response.Content.ReadAsStringAsync().ContinueWith(t => { if (t.IsCompleted) { requestResult.IsSuccess = true; requestResult.Result = t.Result; callback?.Invoke(requestResult); } }); } } catch (Exception e) { if (e.InnerException != null) requestResult.Message = e.InnerException.Message; else if (e.Message.Contains("已取消一个任务")) requestResult.Message = "连接服务器超时,请重试"; else if (e.Message.Contains("404")) requestResult.Message = "连接服务器404,请重试"; else requestResult.Message = e.Message; callback?.Invoke(requestResult); } } public static async void AsyncGet(string url, Action<RequestResult> callback, int timeoutSeconds = 10) { var requestResult = new RequestResult(); if (!IsConnectedInternet()) { requestResult.Message = "网络连接错误,请稍后再试。"; callback?.Invoke(requestResult); return; } try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6"); client.Timeout = new TimeSpan(0, 0, timeoutSeconds); var response = await client.GetAsync(url); //确保HTTP成功状态值 response.EnsureSuccessStatusCode(); //await异步读取最后的JSON await response.Content.ReadAsStringAsync().ContinueWith(t => { if (t.IsCompleted) { requestResult.IsSuccess = true; requestResult.Result = t.Result; callback?.Invoke(requestResult); } }); } } catch (Exception e) { if (e.InnerException != null) requestResult.Message = e.InnerException.Message; else if (e.Message.Contains("已取消一个任务")) requestResult.Message = "连接服务器超时,请重试"; else if (e.Message.Contains("404")) requestResult.Message = "连接服务器404,请重试"; else requestResult.Message = e.Message; callback?.Invoke(requestResult); } } public static async void AsyncPut(string url, string body, Action<RequestResult> callback, int timeoutSeconds = 10) { var requestResult = new RequestResult(); if (!IsConnectedInternet()) { requestResult.Message = "网络连接错误,请稍后再试。"; callback?.Invoke(requestResult); return; } try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6"); client.Timeout = new TimeSpan(0, 0, timeoutSeconds); HttpContent content = new StringContent(body); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var response = await client.PutAsync(url, content); //确保HTTP成功状态值 response.EnsureSuccessStatusCode(); //await异步读取最后的JSON await response.Content.ReadAsStringAsync().ContinueWith(t => { if (t.IsCompleted) { requestResult.IsSuccess = true; requestResult.Result = t.Result; callback?.Invoke(requestResult); } }); } } catch (Exception e) { if (e.InnerException != null) requestResult.Message = e.InnerException.Message; else if (e.Message.Contains("已取消一个任务")) requestResult.Message = "连接服务器超时,请重试"; else if (e.Message.Contains("404")) requestResult.Message = "连接服务器404,请重试"; else requestResult.Message = e.Message; callback?.Invoke(requestResult); } } public static async void AsyncDelete(string url, Action<RequestResult> callback, int timeoutSeconds = 10) { var requestResult = new RequestResult(); if (!IsConnectedInternet()) { requestResult.Message = "网络连接错误,请稍后再试。"; callback?.Invoke(requestResult); return; } try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6"); client.Timeout = new TimeSpan(0, 0, timeoutSeconds); var response = await client.DeleteAsync(url); //确保HTTP成功状态值 response.EnsureSuccessStatusCode(); //await异步读取最后的JSON await response.Content.ReadAsStringAsync().ContinueWith(t => { if (t.IsCompleted) { requestResult.IsSuccess = true; requestResult.Result = t.Result; callback?.Invoke(requestResult); } }); } } catch (Exception e) { if (e.InnerException != null) requestResult.Message = e.InnerException.Message; else if (e.Message.Contains("已取消一个任务")) requestResult.Message = "连接服务器超时,请重试"; else if (e.Message.Contains("404")) requestResult.Message = "连接服务器404,请重试"; else requestResult.Message = e.Message; callback?.Invoke(requestResult); } } 上面使用到的RequestResult类: public class RequestResult : IDisposable { public bool IsSuccess { get; set; } public string Result { get; set; } public string Message { get; set; } public RequestResult(bool isSuccess = false, string result = "", string message = "") { IsSuccess = isSuccess; Result = result; Message = message; } ~RequestResult() { Dispose(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this);//不需要再调用本对象的Finalize方法 } protected virtual void Dispose(Boolean disposing) { if (disposing) { //--- 清理托管资源 ---// } //--- 清理非托管资源 ---// } }
2.WebRequest和webresponse
实例①
public void GetHtml() { var url = "http://www.360doc.com/content/11/0427/03/1947337_112596569.shtml"; string strBuff = "";//定义文本字符串,用来保存下载的html int byteRead = 0; HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); //若成功取得网页的内容,则以System.IO.Stream形式返回,若失败则产生ProtoclViolationException错 误。在此正确的做法应将以下的代码放到一个try块中处理。这里简单处理 Stream reader = webResponse.GetResponseStream(); ///返回的内容是Stream形式的,所以可以利用StreamReader类获取GetResponseStream的内容,并以StreamReader类的Read方法依次读取网页源程序代码每一行的内容,直至行尾(读取的编码格式:UTF8) StreamReader respStreamReader = new StreamReader(reader,Encoding.UTF8); ///分段,分批次获取网页源码 char[] cbuffer = new char[1024]; byteRead = respStreamReader.Read(cbuffer,0,256); while (byteRead != 0) { string strResp = new string(char,0,byteRead); strBuff = strBuff + strResp; byteRead = respStreamReader.Read(cbuffer,0,256); } using (StreamWriter sw = new StreamWriter("e:\\\\ouput.txt"))//将获取的内容写入文本 { htm = sw.ToString();//测试StreamWriter流的输出状态,非必须 sw.Write(strBuff); } }
实例②
WebRequest的方式(该方式是post请求的时候传入json字符串转换成流的形式,无需再将json转换成需要的实体对象了),所以这种方式只需写一个公共的方法,每次调用的时候传入地址和参数即可 公共方法如下: public class WebRequestHelper { public static string GetRequest(string url) { string responseStr = string.Empty; WebRequest request = WebRequest.Create(url); request.Method = "Get"; var response = request.GetResponse(); Stream ReceiveStream = response.GetResponseStream(); using (StreamReader stream = new StreamReader(ReceiveStream, Encoding.UTF8)) { responseStr = stream.ReadToEnd(); } return responseStr; } public static string PostRequest(string url, string postParameter) { string responseStr = string.Empty; WebRequest request = WebRequest.Create(url); request.Method = "Post"; request.ContentType = "application/json"; byte[] requestData = System.Text.Encoding.UTF8.GetBytes(postParameter); request.ContentLength = requestData.Length; Stream newStream = request.GetRequestStream(); newStream.Write(requestData, 0, requestData.Length); newStream.Close(); var response = request.GetResponse(); Stream ReceiveStream = response.GetResponseStream(); using (StreamReader stream = new StreamReader(ReceiveStream, Encoding.UTF8)) { responseStr = stream.ReadToEnd(); } return responseStr; } /// <summary> /// Http的 WebRequest的特定实现 /// </summary> /// <param name="Url"></param> /// <param name="JSONData"></param> /// <returns></returns> public static string GetResponseData(string Url, string JSONData) { byte[] bytes = Encoding.UTF8.GetBytes(JSONData); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; request.ContentLength = bytes.Length; request.ContentType = "application/json"; Stream reqstream = request.GetRequestStream(); reqstream.Write(bytes, 0, bytes.Length); 分布式技术 webapi