C# 通过 HttpWebRequest发送数据以及服务器通过Request请求获取数据, 后台请求的三种类型"application/x-www-form-urlencoded"和"multipart/form-data"以及"application/json",对应的服务器端应该获取数据参数的方法
C#中HttpWebRequest的用法详解 可参考:
C#中HttpWebRequest的用法详解
C# HttpWebRequest详解
C# 服务器通过Request获取参数 可参考:
C# WebService 接口 通过Request请求获取json参数
一、客户端和服务器传输数据的类
1、后台程序发送HTTP请求的Class,服务器端也要添加该类
namespace WebApiInvoke{ /// <summary> /// 后台程序发送HTTP请求数据的类 /// </summary> class RequestDataModel { /// <summary> /// 姓名 /// </summary> public string DataName { get; set; } /// <summary> /// 性别 /// </summary> public string DataSex { get; set; } /// <summary> /// 结果 /// </summary> public string DataResult { get; set; } /// <summary> /// 年龄 /// </summary> public int DataAge { get; set; } }}
2、服务端返回HTTP请求的数据class,客户端也要有
namespace ServiceTest{ /// <summary> /// WebService 服务端返回的类 /// </summary> public class WebServiceWriteBack { public bool Success { get; set; } = true; public string Data { get; set; } = string.Empty; }}
二、“application/json”:
1、后台程序(客户端)发送HTTP请求(request.Method = “POST”、request.ContentType = “application/json”),
a.客户端代码:
namespace WebApiInvoke{ class HttpApiRequestHelper { /// <summary> /// 使用HttpWebRequest发送一个POST请求 /// </summary> /// <param name="url">请求的地址</param> /// <param name="dto">发送的数据对象</param> /// <returns></returns> public static string HttpJsonPost(string url, object dto) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.KeepAlive = false; request.AllowAutoRedirect = true; request.Accept = "application/json"; request.ContentType = "application/json"; string strContent = JsonConvert.SerializeObject(dto); //序列化为字符串,可以使用自己项目中封装的json方法 using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream())) { dataStream.Write(strContent); } // 获取服务器返回的响应体 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); string encoding = response.ContentEncoding; if (encoding == null || encoding.Length < 1) { encoding = "UTF-8"; //默认编码 } StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)); string retString = reader.ReadToEnd(); return retString; } }}
服务器端通过Request.InputStream获取json数据,并做相应的处理;
需要NuGet程序包中安装Microsoft.AspNetCore.Mvc.WebApiCompatShim,并usingSystem.Web.Http;
b.服务器端对应的代码
using Newtonsoft.Json;using System;using System.IO;using System.Web;using System.Web.Http;namespace ServiceTest{ /// WebService 接口 通过Request请求获取json参数 class GetRequestDataHelper : ApiController { /// <summary> /// 通过Request请求获取json参数 /// 对应request.ContentType = "application/json" /// </summary> /// <returns></returns> public WebServiceWriteBack GetRequestJsonData() { // 服务器端回写数据库的类 WebServiceWriteBack writeBack = new WebServiceWriteBack(); HttpContextBase context = Request.Properties["MS_HttpContext"] as HttpContextBase; HttpRequestBase request = context.Request; string data = string.Empty; using (Stream stream = request.InputStream)// 读取Json数据 { stream.Position = 0; using (StreamReader streamReader = new StreamReader(stream)) { data = streamReader.ReadToEnd(); } } // 将Json数据转换为对象 RequestDataModel data1 = JsonConvert.DeserializeObject<RequestDataModel>(data); #region 对传进来的 DataModel 进行处理 并对要回写的WebServiceWriteBack类进行赋值 if (string.IsNullOrEmpty(data1.DataSex)) { writeBack.Success = true; writeBack.Data = "成功了!"; } #endregion return writeBack; } }}
三、表单:
1、传统的表单数据是"DataName=1&DataSex=dadada&DataResult=S201FR&DataAge=1"一个字符串中间用‘&’分割;
后台程序(客户端)发送HTTP请求(request.Method = “POST”、request.ContentType = “application/x-www-form-urlencoded”),
a.客户端代码:
/// <summary> /// HttpWebRequest Post请求 /// application/x-www-form-urlencoded /// "DataName=1&DataSex=dadada&DataResult=S201FR&DataAge=1" /// </summary> /// <param name="postUrl">请求地址</param> /// <param name="postData">请求参数(json格式请求数据时contentType必须指定为application/json)</param> /// <param name="result">返回结果</param> /// <param name="contentType">请求类型</param> /// <returns>返回结果</returns> public static bool WebHttpPost(string postUrl, string postData, out string result, string contentType = "application/x-www-form-urlencoded") { try { Encoding encoding = Encoding.GetEncoding("gb2312"); byte[] byteArray = encoding.GetBytes(postData); HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(postUrl); httpWebRequest.Method = "POST"; httpWebRequest.ContentType = contentType; httpWebRequest.ContentLength = byteArray.Length; httpWebRequest.AllowAutoRedirect = true; using (Stream stream = httpWebRequest.GetRequestStream()) { stream.Write(byteArray, 0, byteArray.Length); // 写入参数 } // 获取服务器返回的响应体 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; using (Stream responseStream = httpWebResponse.GetResponseStream()) { StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("UTF-8")); result = streamReader.ReadToEnd(); // 请求返回的数据 streamReader.Close(); } return true; } catch (Exception ex) { result = ex.Message; return false; } }
b.服务器端通过Request.Form获取表单数据,并做相应的处理;
using Newtonsoft.Json;using System;using System.IO;using System.Web;using System.Web.Http;namespace ServiceTest{ /// <summary> /// 通过Request请求获取表单参数 /// 对应contentType = "application/x-www-form-urlencoded"和contentType = "multipart/form-data" /// </summary> /// <returns></returns> public WebServiceWriteBack GetRequestFromData() { // 服务器端回写数据库的类 WebServiceWriteBack writeBack = new WebServiceWriteBack(); HttpContextBase context = Request.Properties["MS_HttpContext"] as HttpContextBase; HttpRequestBase request = context.Request; RequestDataModel data1 = new RequestDataModel() { DataName = request.Form["DataName"]?.ToString(), DataSex = request.Form["DataSex"]?.ToString(), DataAge = Convert.ToInt32(request.Form["DataAge"]?.ToString()), DataResult = request.Form["DataResult"]?.ToString() }; #region 对传进来的 DataModel 进行处理 并对要回写的WebServiceWriteBack类进行赋值 if (string.IsNullOrEmpty(data1.DataSex)) { writeBack.Success = true; writeBack.Data = "成功了!"; } #endregion return writeBack; } }}
2、“multipart/form-data”
包含异步请求方法HttpPostAsync和HttpPostFromData方法
a.客户端代码,两个方法
using Newtonsoft.Json;using Newtonsoft.Json.Linq;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;using System.Text;namespace WebApiInvoke{ class HttpApiRequestHelper { /// <summary> /// Async异步请求 POST /// </summary> /// <param name="urlStr">请求的地址</param> /// <param name="jsonStr">Json字符串</param> /// <returns></returns> public static string HttpPostAsync(string urlStr, string jsonStr) { string content = ""; try { Dictionary<string, string> map = JsonStringToKeyValuePairs(jsonStr); var mfdc = new System.Net.Http.MultipartFormDataContent(); mfdc.Headers.Add("ContentType", "multipart/form-data");//声明头部 foreach (string key in map.Keys) { mfdc.Add(new System.Net.Http.StringContent(map[key]), key);//参数, 内容在前,参数名称在后 } var clientTask = new System.Net.Http.HttpClient().PostAsync(urlStr, mfdc);//发起异步请求 clientTask.Wait();//等待请求结果 if (clientTask.Result.IsSuccessStatusCode) { //请求正常 var resultTask = clientTask.Result.Content.ReadAsStringAsync();//异步读取返回内容 resultTask.Wait();//等读取返回内容 content = resultTask.Result;//返回内容字符串 } else { //请求异常 content = "失败"; } } catch (Exception ex) { content = ex.Message; } return content; } /// <summary> /// multipart/form-data POST请求 /// </summary> /// <param name="url">请求的地址</param> /// <param name="jsonStr">Json字符串</param> /// <returns></returns> public static string HttpPostFromData(string url, string jsonStr) { string content = ""; try { string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = Encoding.ASCII.GetBytes("/r/n--" + boundary + "/r/n"); byte[] endbytes = Encoding.ASCII.GetBytes("/r/n--" + boundary + "--/r/n"); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); request.ContentType = "multipart/form-data; boundary=" + boundary; request.Method = WebRequestMethods.Http.Post; request.KeepAlive = true; request.Timeout = -1; CredentialCache credentialCache = new CredentialCache(); credentialCache.Add(new Uri(url), "Basic", new NetworkCredential("user", "user")); request.Credentials = credentialCache; request.ServicePoint.Expect100Continue = false; Dictionary<string, string> map = JsonStringToKeyValuePairs(jsonStr); using (Stream stream = request.GetRequestStream()) { //1.1 key/value string formdataTemplate = "Content-Disposition: form-data; name=/"{0}/"/r/n/r/n{1}"; if (map != null) { foreach (string key in map.Keys) { stream.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, map[key]); byte[] formitembytes = Encoding.GetEncoding("UTF-8").GetBytes(formitem); stream.Write(formitembytes, 0, formitembytes.Length); } } stream.Write(endbytes, 0, endbytes.Length); } //2.WebResponse HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream responsestream = response.GetResponseStream()) { using (StreamReader sr = new StreamReader(responsestream)) { content = sr.ReadToEnd(); } } } catch (Exception ex) { content = ex.Message; } return content; } /// <summary> /// JSON格式转Dictionary /// </summary> /// <param name="jsonStr"></param> /// <returns></returns> public static Dictionary<string, string> JsonStringToKeyValuePairs(string jsonStr) { char jsonBeginToken = '{'; char jsonEndToken = '}'; if (string.IsNullOrEmpty(jsonStr)) { return null; } //验证json字符串格式 if (jsonStr[0] != jsonBeginToken || jsonStr[jsonStr.Length - 1] != jsonEndToken) { throw new ArgumentException("非法的Json字符串!"); } var resultDic = new Dictionary<string, string>(); var jobj = JObject.Parse(jsonStr); JsonOn(jobj, resultDic); return resultDic; } private static Dictionary<string, string> JsonOn(JToken jobT, Dictionary<string, string> Dic) { //找出包含嵌套的字段列 if (jobT is JObject jobj && jobj.Properties().Count() > 0) { foreach (var item in jobj.Properties()) { JsonProperties(item, Dic); } } else { Dic.Add(jobT.Path, jobT.ToString()); return Dic; } return Dic; } private static Dictionary<string, string> JsonProperties(JProperty jobj, Dictionary<string, string> Dic) { return JsonOn(jobj.Value, Dic); } }}