HTTP请求是常见的web开发请求,简历也容易上手,当然对于 前端来说,jsweb的http很熟悉,而换种语言的c#是怎样的呢?
Newtonsoft.Json是一个处理json格式的c#库,我们可以去下载它并学习使用它。
我的工具库里使用了HttpClient。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Security;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Xml.Serialization;
using DongliCAD.utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using Bricscad.ApplicationServices;
using Bricscad.EditorInput;
using DongliCAD.common;
namespace DongliCAD.utils
{
class HttpUtil
{
///
/// get请求
///
///
///
public static JObject GetResponse(string url)
{
try
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
HttpResponseMessage response = httpClient.GetAsync(url).Result;
StatusCodeHandler(response);
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
return jo;
}
}
catch(Exception e)
{
string msg = e.InnerException.InnerException.Message;
if(msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return new JObject();
}
public static T GetResponse(string url)
where T : class, new()
{
T result = default(T);
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
try {
HttpResponseMessage response = httpClient.GetAsync(url).Result;
StatusCodeHandler(response);
if (response.IsSuccessStatusCode)
{
Task t = response.Content.ReadAsStringAsync();
string s = t.Result;
result = JsonConvert.DeserializeObject(s);
}
}
catch(Exception e)
{
string msg = e.InnerException.InnerException.Message;
if(msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return result;
}
///
/// post请求
///
///
/// post数据
///
public static JObject PostResponse(string url, string postData)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpContent httpContent = new StringContent(postData);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
try {
HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;
StatusCodeHandler(response);
AuthorizationHandler(response, url);
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
return jo;
}
}
catch (Exception e)
{
string msg = e.InnerException.InnerException.Message;
if (msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return new JObject();
}
private static Boolean StatusCodeHandler(HttpResponseMessage response)
{
Boolean ct = true;
String statusCode = response.StatusCode.ToString();
string result = response.Content.ReadAsStringAsync().Result;
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
if (statusCode == HttpStatusCode.Unauthorized.ToString())
{
AlertUtil.Show("请重新登陆");
LoginForm login = new LoginForm();
login.ShowDialog();
} else if (statusCode == HttpStatusCode.Forbidden.ToString())
{
AlertUtil.Show("禁止访问" + jo["data"]["msg"]);
}
else if (statusCode == HttpStatusCode.NotFound.ToString())
{
AlertUtil.Show("请求失败");
}else if(statusCode == HttpStatusCode.BadRequest.ToString())
{
AlertUtil.Show("400");
}
return ct;
}
private static void AuthorizationHandler(HttpResponseMessage response, string url)
{
Regex reg = new Regex("(.+)/login$");
Boolean isLogin = reg.IsMatch(url);
if (isLogin)
{
GlobalData.Authorization = getHeaderByKey(response, "Authorization");
}
}
private static string getHeaderByKey(HttpResponseMessage response, string key)
{
string result = "";
string header = response.Headers.ToString();
string[] headers = header.Split("\r\n".ToCharArray());
if(headers.Count() > 0)
{
foreach (string item in headers)
{
Regex reg = new Regex("^" + key + ":(.+)");
if (reg.IsMatch(item))
{
string[] tokens = item.Split(':');
if (tokens[0].ToString() == key)
{
result = tokens[1].ToString();
break;
}
}
else
{
reg = new Regex("^" + key + "=(.+)");
if (reg.IsMatch(item))
{
string[] tokens = item.Split('=');
if (tokens[0].ToString() == key)
{
result = tokens[1].ToString();
break;
}
}
}
}
}
return result;
}
///
/// 发起post请求
///
///
/// url
/// post数据
///
public static T PostResponse(string url, string postData)
where T : class, new()
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpContent httpContent = new StringContent(postData);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
T result = default(T);
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
try
{
HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;
StatusCodeHandler(response);
if (response.IsSuccessStatusCode)
{
Task t = response.Content.ReadAsStringAsync();
string s = t.Result;
result = JsonConvert.DeserializeObject(s);
}
}
catch (Exception e)
{
string msg = e.InnerException.InnerException.Message;
if (msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return result;
}
///
/// put请求
///
///
/// put数据
///
public static JObject PutResponse(string url, string putData = "")
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpContent httpContent = new StringContent(putData);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
try
{
HttpResponseMessage response = httpClient.PutAsync(url, httpContent).Result;
StatusCodeHandler(response);
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
return jo;
}
}
catch (Exception e)
{
string msg = e.InnerException.InnerException.Message;
if (msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return new JObject();
}
///
/// delete请求
///
///
///
public static JObject DeleteResponse(string url)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
try
{
HttpResponseMessage response = httpClient.DeleteAsync(url).Result;
StatusCodeHandler(response);
string statusCode = response.StatusCode.ToString();
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
return jo;
}
}
catch (Exception e)
{
string msg = e.InnerException.InnerException.Message;
if (msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return new JObject();
}
private static void exceptionHandler(string msg)
{
throw new DyConnectException(msg);
}
}
}
其中
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
是我登陆成功后返回的token,我把token放在header放在头部传给后台,如果具体业务不一样,可以修改。
使用try…catch当连接后台不成功时抛出异常。
DyConnectException是我自定义的一个异常类,用于处理连接后台不成功时的异常。
DyConnectException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DongliCAD
{
class DyConnectException : Exception
{
public int status = 911;
public string message;
public DyConnectException(string message)
{
this.message = message;
}
}
}
其中Get和Post我提供了2种方式请求,一个是返回json格式的字段串,一个是解析成对象。
JObject jObject = HttpUtil.GetResponse("请求的url地址");
取数据方式:jObject["code"].ToString()
或jObject["code"]["code1"].ToString()
ItemTypeRootVo itemTypeRootVo = HttpUtil.GetResponse("请求的url地址");
ItemTypeRootVo是我自定义的对象,比如如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DongliCAD.vo
{
public class ItemTypeRootVo
{
///
///
///
public int code { get; set; }
///
///
///
public string msg { get; set; }
///
///
///
public int error { get; set; }
///
///
///
public List data { get; set; }
}
public class ItemTypeVo
{
///
///
///
public string uid { get; set; }
///
/// 总装图
///
public string itemTypeName { get; set; }
///
/// 类型
///
public string userTitle1 { get; set; }
///
/// 中心高
///
public string userTitle2 { get; set; }
///
/// 总中心距
///
public string userTitle3 { get; set; }
///
/// 级数
///
public string userTitle4 { get; set; }
///
/// 输入轴轴径
///
public string userTitle5 { get; set; }
///
/// 输出轴轴径
///
public string userTitle6 { get; set; }
///
/// 输出力矩
///
public string userTitle7 { get; set; }
///
///
///
public string userTitle8 { get; set; }
///
///
///
public int order { get; set; }
}
}
那么在请求成功后,会自动把json数据解析成ItemTypeRootVo对象,相对来说更方便些。
JObject jObj = new JObject();
jObj.Add(new JProperty("userId", userName));
jObj.Add(new JProperty("password", password));
JObject result = HttpUtil.PostResponse("请求的url地址", jObj.ToString());
或者传递数组
JObject jObj = new JObject();
JArray jArray = new JArray();
jObj.Add(new JProperty("uid", workspaceCadInfoVo.itemRevUid));
jObj.Add(new JProperty("ctype", "ITEMREVISION"));
jArray.Add(jObj);
JObject result = HttpUtil.PostResponse("请求的url地址", jArray.ToString());
有时候我们需要上传文件,同时也上传数据。方法如下,以异步方式上传
///
/// post请求
///
///
/// post数据
///
public static JObject PostFileResponse(string url, MultipartFormDataContent postData)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
//HttpContent httpContent = new FormCo StringContent(postData);
//postData.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
if (GlobalData.Authorization.Length > 0)
{
httpClient.DefaultRequestHeaders.Add("Authorization", GlobalData.Authorization);
}
try
{
HttpResponseMessage response = httpClient.PostAsync(url, postData).Result;
StatusCodeHandler(response);
AuthorizationHandler(response, url);
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
return jo;
}
}
catch (Exception e)
{
string msg = e.InnerException.InnerException.Message;
if (msg == "无法连接到远程服务器")
{
AlertUtil.Show("服务器无响应,请重新配置环境");
exceptionHandler("连接失败");
}
}
return new JObject();
}
使用方式
MultipartFormDataContent dataContent = new MultipartFormDataContent();
//传文件
string pdfFileName = "test.pdf";
FileStream pdfFsRead = new FileStream("D:/test/" + pdfFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
byte[] pdfBytes = new byte[(int)pdfFsRead.Length];
pdfFsRead.Read(pdfBytes, 0, pdfBytes.Length);
//ByteArrayContent pdfArrayContent = new ByteArrayContent(File.ReadAllBytes("D:/test/" + pdfFileName));
ByteArrayContent pdfArrayContent = new ByteArrayContent(pdfBytes);
pdfArrayContent.Headers.Add("Content-Type", "multipart/form-data");
dataContent.Add(pdfArrayContent, "files", pdfFileName);
//传数据,注意格式是value-key,不是key-value
dataContent.Add(new StringContent("123"), "itemRevisionUid");
dataContent.Add("456", "datasetUid");
//请求接口
JObject jObject = HttpUtil.PostFileResponse("请求的url地址", dataContent);
上面将文件和数据都放到MultipartFormDataContent对象里.
后台接口类似如下(使用kotlin语法写的。和java差不多)
/**
* 保存图纸和pdf文档
*/
@PostMapping("/saveDrawingno")
fun saveDrawingno(
@RequestParam itemRevisionUid:Long,@RequestParam datasetUid: Long,
@RequestParam files: Array): ResponseEntity {
//逻辑部分
}
实现了即上传文件又上传数据的功能。
文件下载包括同步下载和异常下载。
工具类HttpDownUtil.cs如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Security;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Xml.Serialization;
using DongliCAD.utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
namespace DongliCAD.utils
{
class HttpDownUtil
{
/**********************************************上传***************************************************************************/
public static void SetHeaderValue(WebHeaderCollection header, string name, string value)
{
var property = typeof(WebHeaderCollection).GetProperty("InnerCollection",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (property != null)
{
var collection = property.GetValue(header, null) as NameValueCollection;
collection[name] = value;
}
}
/**********************************************下载***************************************************************************/
/********************同步下载***************************/
///
/// 同步下载
/// Http下载文件
///
public static string HttpDownloadFile(string url, string path)
{
// 设置参数
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
if (GlobalData.Authorization.Length > 0)
{
request.Headers.Add("Authorization", GlobalData.Authorization);
}
//发送请求并获取相应回应数据
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
Stream responseStream = response.GetResponseStream();
//创建本地文件写入流
Stream stream = new FileStream(path, FileMode.Create);
byte[] bArr = new byte[1024];
int size = responseStream.Read(bArr, 0, (int)bArr.Length);
while (size > 0)
{
stream.Write(bArr, 0, size);
size = responseStream.Read(bArr, 0, (int)bArr.Length);
}
stream.Close();
responseStream.Close();
return path;
}
/********************异步下载***************************/
///
/// 异步回调
///
/// Result.
private static void BeginResponseCallback(IAsyncResult result)
{
DownloadTmp downloadInfo = (DownloadTmp)result.AsyncState;
HttpWebRequest Request = downloadInfo.webRequest;
HttpWebResponse Response = (HttpWebResponse)Request.EndGetResponse(result);
if (Response.StatusCode == HttpStatusCode.OK || Response.StatusCode == HttpStatusCode.Created)
{
string filePath = downloadInfo.filePath;
if (File.Exists(filePath))
{
File.Delete(filePath);
}
//FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
FileStream fs = File.OpenWrite(filePath);
Stream stream = Response.GetResponseStream();
int count = 0;
int num = 0;
if (Response.ContentLength > 0)
{
downloadInfo.AllContentLength = Response.ContentLength;
var buffer = new byte[2048 * 100];
do
{
num++;
count = stream.Read(buffer, 0, buffer.Length);
downloadInfo.currentContentLength = num * buffer.Length;
fs.Write(buffer, 0, count);
if (downloadInfo.loadingCallback != null)
{
float pro = (float)fs.Length / Response.ContentLength * 100;
downloadInfo.loadingCallback((int)pro);
}
} while (count > 0);
}
fs.Close();
Response.Close();
if (downloadInfo.succeedCallback != null)
{
downloadInfo.succeedCallback();
}
}
else
{
Response.Close();
if (downloadInfo.failedCallback != null)
{
downloadInfo.failedCallback();
}
}
}
///
/// 下载文件,异步
///
/// 下载路径
/// 文件下载路径
///
public static void HttpDownloadFileAsyn(string URL, ref DownloadTmp downloadInfo)
{
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(URL);
downloadInfo.webRequest = Request;
Request.BeginGetResponse(BeginResponseCallback, downloadInfo);
}
}
///
/// 下载请求信息
///
public class DownloadTmp
{
///
/// 文件名
///
public string fileName;
///
/// 下载路径
///
public string filePath;
///
/// 下载进度回调
///
public Action loadingCallback;
///
/// 完成回调
///
public Action succeedCallback;
///
/// 失败回调
///
public Action failedCallback;
///
/// webRequest
///
public HttpWebRequest webRequest;
public long AllContentLength;
public long currentContentLength;
}
}
同步下载:HttpDownloadFile()
异步下载:HttpDownloadFileAsyn()
使用方式也很简单
DownloadTmp downloadTmp = new DownloadTmp();
downloadTmp.filePath = @“D:\test\666.txt”;
HttpDownloadZip(downUrl, ref downloadTmp);
其中在外部我们也可以访问downloadTmp里的参数。谁让它用ref修饰呢