一、使用jQuery Ajax访问
(一)、表单传参( [FromForm])
数据类型:Object
ContenyType类型:application/x-www-form-urlencoded
1
var model = { name: "刘大大", age: 23, sex: true };
前台请求
var model = { name: "刘大大", age: 23, sex: true };
$.ajax({
url: "http://localhost:9001/API/Default/FormCall",
type: "POST",
async: true,
dataType: "json",
data: model,
contentType: "application/x-www-form-urlencoded",
success: function (data) {
console.log("data:");
console.log(data);
}
});
(二)、JSON字符串[FromBdy]
数据类型:Json
ContenyType类型:application/json
1
var json = '{"name":"刘大大","age":23,"sex":true}';
也可以使用JSON.stringify(Object)将Object转换为JSON字符串
前端请求
var model = { name: "刘大大", age: 23, sex: true };
$.ajax({
url: "http://localhost:9001/API/Default/BodyCall",
type: "POST",
async: true,
dataType: "json",
data: JSON.stringify(model),
contentType: "application/json",
success: function (data) {
console.log("data:");
console.log(data);
}
});
(三)、文件上传
建立FormData对象
数据类型:FromData
ContenyType类型false, //必须false才会避开jQuery对 formdata 的默认处理 processData类型: false, //必须false才会自动加上正确的Content-Type
html
1
<input type="file" multiple id="file" />
JS获取文件对象
var file = document.getElementById("file");
var files = file.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
formData.append(files[i].name, files[i]);
}
formData.append("name", "刘大大");//可追加参数
AJAX请求
$.ajax({
url: "http://localhost:9001/API/Default/Upload",
type: "POST",
async: true,
dataType: "json",
data: formData,
contentType: false,
processData: false,
success: function (data) {
console.log(data);
}
});
完整HTML源码
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<div>
<input type="button" id="fromform" value="Form传参" /><hr />
<input type="button" id="frombody" value="Body传参" /><hr />
<input type="file" multiple id="file" name="上传文件" /><hr />
</div>
<script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.js"></script>
<script>
/**
* FromForm
* */
var fromform = document.getElementById("fromform");
$(fromform).click(function () {
var url = 'http://localhost:9001/API/Default/FormCall';
var model = { name: "刘大大", age: 23, sex: true };
$.ajax({
url: url,
type: "POST",
async: true,
data: model,
contentType: "application/x-www-form-urlencoded",
success: function (data) {
console.log(data);
alert(JSON.stringify(data));
},
error: function (result) {
console.log(result);
}
});
});
/**
* FromBody
* */
$('#frombody').click(function () {
var url = 'http://localhost:9001/API/Default/BodyCall';
var json = '{"name":"刘大大","age":23,"sex":true}';
$.ajax({
url: url,
type: "POST",
async: true,
data: json,
contentType: "application/json",
success: function (data) {
console.log(data);
alert(JSON.stringify(data));
},
error: function (result) {
console.log(result);
}
});
});
/**
* FormData
* */
var file = document.getElementById("file");
file.onchange = function () {
var file = document.getElementById("file");
var files = file.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
formData.append(files[i].name, files[i]);
}
formData.append("name", "刘大大");
var isUploadByJs = true;
var url = isUploadByJs ? 'http://localhost:9001/API/Default/Upload' : 'http://localhost:9002/Home/Upload';
$.ajax({
url: url,
type: "POST",
async: true,
dataType: "json",
data: formData,
contentType: false, //必须false才会避开jQuery对 formdata 的默认处理
processData: false, //必须false才会自动加上正确的Content-Type
headers: { ReadTime: Date.now() },
beforeSend: function (xhr) {
xhr.setRequestHeader('Author', 'liudada');
},
success: function (data) {
console.log(data);
alert(JSON.stringify(data));
},
error: function (result) {
console.log(result);
}
});
}
</script>
二、使用C#后台访问
(一)、Get访问
var url = "http://localhost:57954/API/Default/Test";
using (var client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip }))
{
var taskResponse = client.GetAsync(url);
taskResponse.Wait();
if (taskResponse.IsCompletedSuccessfully)
{
var taskStream = taskResponse.Result.Content.ReadAsStreamAsync();
taskStream.Wait();
using (var reader = new StreamReader(taskStream.Result))
{
jsonString = reader.ReadToEnd();
}
}
}
(二)、Post访问
var url = "http://localhost:57954/API/Default/BodyCall";
var data = new {name="刘大大",age=23,sex=true };
using (var client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip }))
{
var jsonToSend = JsonConvert.SerializeObject(data, Formatting.None, new IsoDateTimeConverter());
var body = new StringContent(jsonToSend, Encoding.UTF8, "application/json");
var taskResponse = client.PostAsync(url, body);
taskResponse.Wait();
if (taskResponse.IsCompletedSuccessfully)
{
var taskStream = taskResponse.Result.Content.ReadAsStreamAsync();
taskStream.Wait();
using (var reader = new StreamReader(taskStream.Result))
{
jsonString = reader.ReadToEnd();
}
}
}
(三)、上传文件
/// <summary>
/// 上传文件
/// </summary>
/// <returns></returns>
[RequestSizeLimit(1_073_741_824)]
public IActionResult Upload()
{
var url = "http://localhost:9001/Api/Default/Upload";
var data = new MultipartFormDataContent();
if (Request.HasFormContentType)
{
var request = Request.Form.Files;
foreach (var item in request)
{
data.Add(new StreamContent(item.OpenReadStream()), item.Name, item.FileName);
}
foreach (var item in Request.Form)
{
data.Add(new StringContent(item.Value), item.Key);
}
}
string jsonString = string.Empty;
using (var client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip }))
{
var taskResponse = client.PostAsync(url, data);
taskResponse.Wait();
if (taskResponse.IsCompletedSuccessfully)
{
var taskStream = taskResponse.Result.Content.ReadAsStreamAsync();
taskStream.Wait();
using (var reader = new StreamReader(taskStream.Result))
{
jsonString = reader.ReadToEnd();
}
}
}
return new JsonResult(jsonString);
}
WebHelper
根据文本定位div并设置属性
$('div:contains("*****"):not(:has(*))').parent().css("display", "none");
.net core模拟发送post和get请求
1年前 46,320 0
string url = "http://www.xxx.com/api/postmsg";
string jsonContent = JsonConvert.SerializeObject(message);
using (var client = new HttpClient())
{
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
//上面代码使http Content-Type 为 application/json; charset=utf-8。如果希望Content-Type为application/json,可以使用下面两行代码
//content.Headers.Remove("Content-Type"); // "{application/json; charset=utf-8}"
//content.Headers.Add("Content-Type", "application/json");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer");
string result = client.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
}
以上为核心代码。
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2
/// <summary>
/// 公共方法—— 发送http post请求 2020年6月2日11:20:42 Dennyhui
/// </summary>
/// <param name="formData">参数</param>
/// <param name="requestUri">请求地址</param>
/// <param name="token">身份验证秘钥,可为空</param>
/// <returns></returns>
public async Task<string> Client_Post(MultipartFormDataContent formData, string requestUri, string token)
{
//从工厂获取请求对象
var client = _httpClientFactory.CreateClient();
//添加请求头
if (!string.IsNullOrWhiteSpace(token))
{
client.DefaultRequestHeaders.Add("Authorization", token);
}
HttpResponseMessage response = client.PostAsync(requestUri, formData).Result;
return response.Content.ReadAsStringAsync().Result;
}
/// <summary>
/// 公共方法—— 发送http get 请求 2020年6月2日11:22:11 Dennyhui
/// <para>最终以url参数的方式提交</para>
/// </summary>
/// <param name="parameters">参数字典,可为空</param>
/// <param name="requestUri">例如/api/Files/UploadFile</param>
/// <returns></returns>
public async Task<string> Client_Get(Dictionary<string, string> parameters, string requestUri, string token)
{
//从工厂获取请求对象
var client = _httpClientFactory.CreateClient();
//添加请求头
if (!string.IsNullOrWhiteSpace(token))
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
}
//拼接地址
if (parameters != null)
{
var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value));
requestUri = string.Concat(requestUri, '?', strParam);
}
client.BaseAddress = new Uri(requestUri);
//client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
return client.GetStringAsync(requestUri).Result;
}
****************************************************
此处内容传输都是用UTF-8编码
1、不带参数发送Post请求
/// <summary>
/// 指定Post地址使用Get 方式获取全部字符串
/// </summary>
/// <param name="url">请求后台地址</param>
/// <returns></returns>
public static string Post(string url)
{
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//获取内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
2、带参数Post请求,指定键值对
/// <summary>
/// 指定Post地址使用Get 方式获取全部字符串
/// </summary>
/// <param name="url">请求后台地址</param>
/// <returns></returns>
public static string Post(string url,Dictionary<string,string> dic)
{
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
#region 添加Post 参数
StringBuilder builder = new StringBuilder();
int i = 0;
foreach (var item in dic)
{
if (i > 0)
builder.Append("&");
builder.AppendFormat("{0}={1}", item.Key, item.Value);
i++;
}
byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
#endregion
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//获取响应内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
3、带参数的Post请求,指定发送字符串内容
/// <summary>
/// 指定Post地址使用Get 方式获取全部字符串
/// </summary>
/// <param name="url">请求后台地址</param>
/// <param name="content">Post提交数据内容(utf-8编码的)</param>
/// <returns></returns>
public static string Post(string url, string content)
{
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
#region 添加Post 参数
byte[] data = Encoding.UTF8.GetBytes(content);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
#endregion
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//获取响应内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
转载方法:
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://fanyi.baidu.com/transcontent");
Encoding encoding = Encoding.UTF8;
string param = "ie=utf-8&source=txt&query=hello&t=1327829764203&token=8a7dcbacb3ed72cad9f3fb079809a127&from=auto&to=auto";
//encoding.GetBytes(postData);
byte[] bs = Encoding.ASCII.GetBytes(param);
string responseData = String.Empty;
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
reqStream.Close();
}
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(),encoding))
{
responseData = reader.ReadToEnd().ToString();
}
context.Response.Write(responseData);
}
***************************************************************
调⽤webApi接⼝通过post⽅式传递实体参数时,发现接⼝那⾥接受不到数据,查找资料后顺利解决,顺便做下学习笔记。
⼀、json格式发送
⾸先将实体序列化为json格式的字符串,然后发送,⽰例代码 如下:
Students student =new Students("1001","张三",20,"男");
string json = JsonConvert.SerializeObject(student);
string url ="http://localhost:34626/api/values";
string result = WebHelper.HttpWebRequest(url, json, Encoding.GetEncoding("utf-8"));
其中,HttpWebRequest⽅法⽰例代码如下:
publicstaticstringHttpWebRequest(string url,string parameters, Encoding encoding,int timeout =120000)
{
var request =(HttpWebRequest)WebRequest.Create(url);
request.Timeout = timeout;
request.CookieContainer =null;
byte[] postData = encoding.GetBytes(parameters);
request.Method ="POST";
request.ContentType ="application/json";
request.ContentLength = postData.Length;
using(Stream stream = request.GetRequestStream())
{
stream.Write(postData,0, postData.Length);
}
var response =(HttpWebResponse)request.GetResponse();
string result;
using(Stream stream = response.GetResponseStream())
{
if(stream ==null)
returnstring.Empty;
using(var reader =new StreamReader(stream, encoding))
{
result = reader.ReadToEnd();
}
}
return result;
}
Post⽅法如下:
//POST api/values
publicstringPost(dynamicvalue)
{
return"value";
}
接收到Json字符串之后再反序列化即可。
结果如下图:
⼆、key/value形式发送
⾸先将实体转换为Dictionary类型,然后构造字符串发送,接⼝⽤实体接收,⽰例代码 如下:
将实体转换为
//
Dictionary<string,object>
var dic = JsonConvert.DeserializeObject<Dictionary<string,object>>(JsonConvert.SerializeObject(student));
StringBuilder builder =new StringBuilder();
foreach(var item in dic)
{
builder.AppendFormat("{0}={1}&", item.Key, item.Value);
}
string url ="http://localhost:34626/api/values";
string result = WebHelper.HttpWebRequest(url, builder.ToString(), Encoding.GetEncoding("utf-8"));
采⽤这种⽅式发送需要对HttpWebRequest⽅法修改⼀⾏代码,如下:
修改如下代码
//
request.ContentType ="application/x-www-form-urlencoded";
Post接⼝⽰例如下:
//POST api/values
publicstringPost(Students value)
{
return"value";
}
结果如下图:
虽然两种⽅式都能传递,但我还是⽐较喜欢序列化为Json格式之后发送,第⼆种⽅式对付简单的实体时⽐较好⽤,但是复杂的就不太好⽤
了。
ok
--------------------------------------------------------
一次HTTP请求,就是一次标准IO操作。请求是I,是输入;响应式O,是输出。任何web开发框架,其实都是在干这两件事:
接受请求并进行解析获取参数
根据参数进行渲染并输出响应内容
所以我们学习一个框架,我认为最首要的是知道如何从请求中获取参数。http请求携带参数的地方主要有下面几个地方:
URL
Header
Body
下面看看ASP.NET Core是如何从这几个位置获取参数的。
通过URL获取参数
通过URL传参是HTTP最最常用的办法。这里简单介绍下URL相关的知识。一个URL主要分成4个部分,以http://localhost:5000/fromurl/test?name=mjzhou&age=10为例:
http:// 协议
localhost:5000 主机地址
/fromurl/test PATH
name=mjzhou&age=10 QueryString
我们通常使用PATH跟QueryString来传递参数。新建一个MVC项目,新建一个Controller名为FromUrlController,通过几个Action来演示如何从URL上获取参数。
通过QuerySting获取参数
Request.Query对象
// /fromurl/test?name=mjzhou
public IActionResult Test()
{
var name = Request.Query["name"];
return Content(name);
}
Request.Query对象包含了本次请求的QueryString的键值对列表,所以可以通过它轻松获取QueryString上携带的参数。
自动参数绑定
// /fromurl/test?name=mjzhou
public IActionResult Test1(string name)
{
return Content(name);
}
如果Action的型参的名称跟QueryString的Key一致,则MVC框架会自动帮我们绑定参数的值,不用手动获取。
public IActionResult Test2([FromQuery(Name = "id")]string bh)
{
return Content(bh);
}
如果参数绑定的名称跟QueryString的Key不一致,可以使用FromQueryAttribute强制指定绑定的Key的名称。
通过PATH获取参数
Request.Path对象
// /fromurl/test3
public IActionResult Test3()
{
var path = Request.Path;
return Content(path);
}
Request.Path对象包含了本次http请求的Path的原始信息,一般可以通过/来分隔,手工获取想要的参数。
自动参数绑定
// /fromurl/Test4/mjzhou/1000
[Route("FromUrl/test4/{name}/{id}")]
public IActionResult Test4(string name, int id)
{
return Content($"{name}/{id}");
}
Path的自动参数绑定,需要配合RouteAttribute实现,RouteAttribute主要是指定一个Path的模板,通过这个模板可以告诉路由是否匹配这个Action,另外一个就是可以告诉参数绑定,如何解析这个path实现参数绑定。
[Route("FromUrl/test6/{name}/{id}")]
public IActionResult Test6([FromRoute(Name ="name")]string xm, [FromRoute(Name = "id")]int bh)
{
return Content($"{xm}/{bh}");
}
如果Action的型参名称跟RouteAttribute模板的中的名称不一样,那么可以使用FromRoute强制指定解析的名称。
[HttpGet("FromUrl/test5/{name}/{id}")]
public IActionResult Test5(string name, int id)
{
return Content($"{name}/{id}");
}
HttpGetAttribute、HttpPostAttribute等attribute同样可以完成RouteAttribute的效果,而且还指定了action接受的HTTP Method的方法,可以说是加强版的RouteAttribute。
从Header上获取参数
添加一个FromHeaderController,通过几个action来演示如果从http headers上获取参数。
Request.Headers对象
// /FromHeader/test
public IActionResult Test()
{
var myName = Request.Headers["myName"];
return Content(myName);
}
Request.Headers是一个字典,包含了本次请求的Headers。所以我们可以通过Request.Headers对象轻松获取某个header的值。
自动参数绑定
public IActionResult Test1([FromHeader]string myName)
{
return Content(myName);
}
通过在action的型参上打上FromHeaderAttribute,可以告诉框架自动从header获取参数。
public IActionResult Test2([FromHeader(Name = "myName")]string name)
{
return Content(name);
}
如果action的型参跟header的key值不一致,可以通过FromHeaderAttribute强制指定匹配的header的key值。
从Body获取参数
我们开发的时候经常通过表单提交数据,或者通过AJAX往后台提交一个JavaScript对象,本质上这些数据都是通过HTTP的Bady提交回去的。新建一个FromBodyController控制器,通过几个Action来演示如何获取Body的参数。
Request.Body对象
public class model1
{
public string NAME { get; set; }
}
public async Task<IActionResult> Test()
{
Request.EnableBuffering();
string body = "";
var stream = Request.Body;
if (stream != null)
{
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(stream, Encoding.UTF8, true, 1024, true))
{
body = await reader.ReadToEndAsync();
}
stream.Seek(0, SeekOrigin.Begin);
}
var model = JsonConvert.DeserializeObject<model1>(body);
return Content(model.NAME);
}
Request.Body是一个Stream,保存了本次请求的body数据。所以我们只要把这个stream读出来,就能获取提交的数据。有了原始的数据,就可以通过反序列化等操作转换为模型,更简单的获取参数了。注意,ASP.NET Core想要读取这个对象,必须先调用Request.EnableBuffering()这个方法。
使用postman测试一下:
YiygVP.md.png
参数自动绑定
public IActionResult Test1([FromBody]model1 model)
{
return Content(model.NAME);
}
使用FromBodyAttribute可以把body的数据自动反序列化成型参的模型。但是请注意使用[FromBody]请求的Content-Type必须是application-json。
使用postman测试下:
Yica1e.md.png
Yicch8.md.png
public IActionResult Test2([FromForm]model1 model)
{
return Content(model.NAME);
}
使用FromFormAttribute可以把body的数据自动反序列化成型参的模型。但是请注意使用[FromForm]请求的Content-Type必须是application/x-www-form-urlencoded。
使用postman测试下:
Yigkge.md.png
YigeHI.md.png
总结
ASP.NET Core获取请求参数主要从URL,Headers,Body等位置获取。我们可以通过Request.Query、Request.Headers、Request.Body来手工获取数据。也可以通过[FromQuery]、[FromHeader]、[Frombody]等Attribute来实现参数的自动绑定。
测试地址:
https://date.nager.at/api/v2/PublicHolidays/2020/US 1.get方法调用接口获取json文件内容
public void GetFunction()
{
string serviceAddress = "http://222.111.999.444:8687/tttr/usercrd/12/b7e50cb45a?userid=9999";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
Response.Write(retString);
}
2.post方法调用接口获取json文件内容
public void PostFunction()
{
string serviceAddress = "http://222.111.999.444:8687/tttr/usercrd/uuu/12/dfd7e4";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
request.ContentType = "application/json";
string strContent = @"{ ""mmmm"": ""89e"",""nnnnnn"": ""0101943"",""kkkkkkk"": ""e8sodijf9""}";
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(strContent);
dataStream.Close();
}
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();
//解析josn
JObject jo = JObject.Parse(retString);
Response.Write(jo["message"]["mmmm"].ToString());
}
public class HttpRequestDemo
{
/// <summary>
/// 请求方式 post 提交 json格式
/// 对应的服务端接口接收 Task<JsonResult> Login(model m)
/// </summary>
public void JsonFormatRequest()
{
//参数对象
var data = new
{
platform = 1,
userName = "xxxxxx",
password = "xxxxxx"
};
//将对象参数序列化成json字符串 ,也可以自己手动拼接
var jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(data);
byte[] bs = Encoding.Default.GetBytes(jsonStr);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(@"http://xxx.com/Api/User/Login");//接口地址
req.Method = "POST"; //请求类型
req.ContentType = "application/json";
req.ContentLength = bs.Length;
//获得请求流
using (Stream reqStream = req.GetRequestStream())
{
//参数写入请求流
reqStream.Write(bs, 0, bs.Length);
reqStream.Close();
//从返回结果流中读取返回数据
StreamReader sr = new StreamReader(req.GetResponse().GetResponseStream(), Encoding.UTF8);
string result = sr.ReadToEnd();
Console.WriteLine(result);//打印返回信息 结果可用Newtonsoft.Json.JsonConvert.DeserializeObject 序列化成自己想要的对象
}
}
/// <summary>
/// 请求方式 Post 提交 body 如 &name=123&xxx 方式传参
/// 对应的服务端接收参数 Task<JsonResult> Login([FromForm]model m)
/// </summary>
public void QueryBodyRequest()
{
//拼接的即将传入的参数对象
var queryStr = "&phone=xxxxx&key=xxxxxx&password=xxxx&type=2";
byte[] bs = Encoding.Default.GetBytes(queryStr);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(@"http://xxx.com/account/login");//接口地址
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = bs.Length;
//请求数据
using (Stream reqStream = req.GetRequestStream())
{
//写入流数据
reqStream.Write(bs, 0, bs.Length);
reqStream.Close();
//从返回结果流中读取数据
StreamReader sr = new StreamReader(req.GetResponse().GetResponseStream(), Encoding.UTF8);
string result = sr.ReadToEnd();
Console.WriteLine(result);//打印返回信息 结果可用Newtonsoft.Json.JsonConvert.DeserializeObject 序列化成自己想要的对象
}
}
/// <summary>
/// 请求方式 Post 提交 Body 方式2 效果同上方法 底层也是 &name=123&xxx 方式传参
/// 对应的服务端接收参数 Task<JsonResult> Login([FromBody]model m)
/// </summary>
public void BodyFormatRequest()
{
try
{
HttpClient myHttpClient = new HttpClient();
var url = "http://www.xxxxx.com/account/login";
var content = new FormUrlEncodedContent(new Dictionary<string, string>() {
{"phone","18888888"},
{"key","CF6D9D9766665367700F9249AD080E9FF9D9" },
{"password","123123" },
{"type","2" },
});
HttpResponseMessage response = myHttpClient.PostAsync(url, content).Result;
var result = response.Content.ReadAsByteArrayAsync().Result;
Console.WriteLine(Encoding.UTF8.GetString(result));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Create Some APIs
Here I use ASP.NET Core WebAPI to creat some RESTful APIs.
[Route("api/[controller]")]
public class PersonsController : Controller
{
// GET: api/persons
[HttpGet]
public IEnumerable Get()
{
return new List
{
new Person{Id = 1 , Name = "catcher wong"},
new Person{Id = 2 , Name = "james"}
};
}
// GET api/persons/5
[HttpGet("{id}")]
public Person Get(int id)
{
return new Person { Id = id, Name = "name" };
}
// POST api/persons
[HttpPost]
public Person Post([FromBody]Person person)
{
if (person == null) return new Person();
return new Person { Id = person.Id, Name = person.Name };
}
// PUT api/persons/
[HttpPut]
public string Put([FromBody]int id)
{
return $"put {id}";
}
// DELETE api/persons/5
[HttpDelete("{id}")]
public string Delete(int id)
{
return $"del {id}";
}
}
Interface Declaration
Create an interface named IPersonApiClient which inherit from IHttpApiClient.
public interface IPersonApiClient : IHttpApiClient { }
Add some methods that need to call APIs.
Every method must have a HTTP attribute that provides the request method and relative URL. The return type should be ITask.
[HttpGet("/api/persons")]
ITask> GetPersonsAsync();
A request URL can be updated dynamically using replacement blocks and parameters on the method. A replacement block is an alphanumeric string surrounded by { and }.
[HttpGet("/api/persons/{id}")]
ITask GetPersonAsync(int id);
When our requst parameters should in request body, we can use some attributes to specify the content, such as JsonContent, FormContent .etc.
[HttpPost("/api/persons")]
ITask AddPersonAsync([JsonContent]Person person);
The following code demonstrates the basic usage.
public interface IPersonApiClient : IHttpApiClient
{
[HttpGet("/api/persons")]
ITask> GetPersonsAsync();
[HttpGet("/api/persons/{id}")]
ITask GetPersonAsync(int id);
[HttpPost("/api/persons")]
ITask AddPersonAsync([JsonContent]Person person);
[HttpPut("/api/persons")]
ITask EditPersonAsync([JsonContent]int id);
[HttpDelete("/api/persons/{id}")]
ITask DeletePersonAsync(int id);
}
The next step is how to retrieve the response of the request.
Retrieving Response
We should create a client first. After creating , what we need to do is call the methods we declared in the interface.
//specify the config
var config = new HttpApiConfig
{
HttpHost = new Uri("http://localhost:9999"),
};
var client = HttpApiClient.Create(config);
var persons = await client.GetPersonsAsync();
Console.WriteLine("GetPersonsAsync result:");
foreach (var item in persons)
{
Console.WriteLine($"{item.Id}-{item.Name}");
}
var person = await client.GetPersonAsync(1000);
Console.WriteLine("GetPersonAsync result:");
Console.WriteLine($"{person.Id}-{person.Name}");
var newPerson = new Person { Id = 999, Name = "999" };
var postResult = await client.AddPersonAsync(newPerson);
Console.WriteLine("AddPersonAsync result:");
Console.WriteLine($"{postResult.Id}-{postResult.Name}");
var editResult = await client.EditPersonAsync(1);
Console.WriteLine("EditPersonAsync result:");
Console.WriteLine($"{editResult}");
var delResult = await client.DeletePersonAsync(1);
Console.WriteLine("DeletePersonAsync result:");
Console.WriteLine($"{delResult}");
第三方 API 概览
我们将开发一个允许用户输入国家代码和年份的应用程序,然后我们将调用第三方 API 来获取该特定国家在该特定年份的公共假期列表。我们将使用的第三方 API 称为 Nager.Date,这是一个全球公共假期 API。
在这里插入图片描述
这是一个非常简单的 API,您可以通过输入以下 URL 在 Postman 中轻松测试此 API。
https://date.nager.at/api/v2/PublicHolidays/2020/US
该 API 的响应是 JSON 格式的公共假期列表,如下所示:
在这里插入图片描述
了解 HttpClient 对象
允许我们在 ASP.NET Core 应用程序中使用第三方 API 的最常见和众所周知的类是 HttpClient 类。此类使我们能够向第三方 API 发送 HTTP 请求并接收从这些 API 返回的 HTTP 响应。 HttpClient 的每个实例都维护着自己的连接池,这使得它可以将自己的请求与其他 HttpClient 实例执行的请求隔离开来。此类还充当更特定 HTTP 客户端的基类。例如,您可以创建 FacebookHttpClient 或 TwitterHttpClient 作为基本 HttpClient 的子类,并且可以使用这些特定的 HTTP 客户端与 Facebook 和 Twitter API 进行通信。
建议创建一个 HttpClient 实例并在整个应用程序生命周期中重复使用它。这是因为为每个请求实例化一个新的 HttpClient 实例很容易耗尽重负载下可用的套接字数量。这主要是因为当 HttpClient 对象被释放,底层套接字不会立即释放。 您可以阅读这篇精彩的博客文章您使用 HttpClient 错误,这会破坏您的软件的稳定性,以获取有关我刚刚提到的问题的更多信息。
在 ASP.NET Core 中使用 HttpClient
正如我上面提到的,我们将创建一个应用程序,允许用户查看任何国家/地区的公共假期列表。让我们创建一个 ASP.NET Core MVC Web 应用程序并创建以下接口。这个接口只有一个 GetHolidays 方法,它有两个参数 countryCode 和 year,我们很快就会从用户那里收到。
public interface IHolidaysApiService
{
Task<List<HolidayModel>> GetHolidays(string countryCode, int year);
}
上面的 GetHolidays 方法返回一个 HolidayModel 列表,它是一个模型类,具有与 Nager.Date API 的响应映射的属性。
public class HolidayModel
{
public string Name { get; set; }
public string LocalName { get; set; }
public DateTime? Date { get; set; }
public string CountryCode { get; set; }
public bool Global { get; set; }
}
接下来,我们需要实现一个 HolidaysApiService 类,该类将实现上面声明的 IHolidaysApiService。请注意我是如何在类中声明私有和静态 HttpClient 变量的,以及它是如何在类的静态构造函数中定义的。这是 Microsoft 官方文档中提到的创建 HttpClient 实例的推荐方法。
public class HolidaysApiService : IHolidaysApiService
{
private static readonly HttpClient client;
static HolidaysApiService()
{
client = new HttpClient()
{
BaseAddress = new Uri("https://date.nager.at")
};
}
}
接下来我们需要定义 GetHolidays 方法,如下所示:
public async Task<List<HolidayModel>> GetHolidays(string countryCode, int year)
{
var url = string.Format("/api/v2/PublicHolidays/{0}/{1}", year, countryCode);
var result = new List<HolidayModel>();
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<List<HolidayModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
else
{
throw new HttpRequestException(response.ReasonPhrase);
}
return result;
}
上面的方法发生了很多事情,所以让我详细解释一下:
第一行是构建 Nager.Date API 的 URL 并使用 year 和 countryCode 参数
var url = string.Format("/api/v2/PublicHolidays/{0}/{1}", year, countryCode);
接下来,我们将使用 GetAsync 方法进行 API 调用,该方法将 GET 请求作为异步操作发送到指定的 Uri。该方法返回 System.Net.Http.HttpResponseMessage 对象,该对象表示包含状态代码和数据的 HTTP 响应消息。
var response = await client.GetAsync(url);
接下来,我们调用 ReadAsStringAsync 方法将 HTTP 内容序列化为字符串
var stringResponse = await response.Content.ReadAsStringAsync();
最后,我们使用 JsonSerializer 将 JSON 响应字符串反序列化为 HolidayModel 对象列表。
result = JsonSerializer.Deserialize<List<HolidayModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
这就是我们使用第三方公共假期 API 所需的全部内容。要使用我们的 HolidaysApiService,我们需要首先在 Startup.cs 类中注册我们的服务。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
}
接下来,我们可以在 HomeController 中注入我们的 HolidaysApiService 并通过传递我们将在 Index action 方法中接收的 countryCode 和 year 参数来调用 GetHolidays 方法。
public class HomeController : Controller
{
private readonly IHolidaysApiService _holidaysApiService;
public HomeController(IHolidaysApiService holidaysApiService)
{
_holidaysApiService = holidaysApiService;
}
public async Task<IActionResult> Index(string countryCode, int year)
{
List<HolidayModel> holidays = new List<HolidayModel>();
holidays = await _holidaysApiService.GetHolidays(countryCode, year);
return View(holidays);
}
}
最后,我们需要一个 Razor 视图来创建一个表单,用户将在其中输入国家代码和年份。表单将提交给上述 Index 操作,然后该操作将调用 GetHolidays 方法。这是 Index.cshtml Razor 视图的代码,显示了一个 HTML 表单和一个用于显示公共假期的表格。
@model List<HolidayModel>
@{
ViewData["Title"] = "Home Page";
}
<div>
<h3 class="display-4">Public Holidays Finder</h3>
<center>
<form asp-controller="Home" asp-action="Index">
<table>
<tr>
<td>Country Code: </td>
<td><input type="text" id="txtCountryCode" name="CountryCode" /></td>
<td>Year: </td>
<td><input type="text" id="txtYear" name="Year" /></td>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
<hr />
</form>
</center>
@if (Model != null && Model.Count > 0)
{
<table class="table table-bordered table-striped table-sm">
<thead>
<tr>
<th>Date</th>
<th>Name</th>
<th>Local Name</th>
<th>Country Code</th>
<th>Global</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Date.Value.ToShortDateString()</td>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
<td>@Html.DisplayFor(modelItem => item.LocalName)</td>
<td>@Html.DisplayFor(modelItem => item.CountryCode)</td>
<td>@Html.DisplayFor(modelItem => item.Global)</td>
</tr>
}
</tbody>
</table>
}
</div>
现在是时候测试我们的应用程序,看看我们是否能够使用第三方 API。在 Visual Studio 中按 F5,您将看到类似于以下内容的页面。您可以输入国家代码,例如美国、德国等,以及一年,例如2021,然后单击“提交”按钮,如果一切顺利,您将看到我们的代码调用第三方 API,从 API 中获取公共假期列表并将其显示在页面上。
在这里插入图片描述
使用 IHttpClientFactory 管理 HttpClient 对象
为了使 HttpClient 实例易于管理,并避免上述套接字耗尽问题,.NET Core 2.1 引入了 IHttpClientFactory 接口,可用于通过依赖注入 (DI) 在应用程序中配置和创建 HttpClient 实例。为了使用 IHttpClientFactory,我们可以通过调用 AddHttpClient(IServiceCollection) 在 Startup.cs 文件中注册它。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
services.AddHttpClient("PublicHolidaysApi", c => c.BaseAddress = new Uri("https://date.nager.at"));
}
可以使用 AddHttpClient 方法注册多个具有不同名称的 HTTP 客户端。 AddHttpClient 方法的第一个参数是客户端的名称,第二个参数是将配置 HttpClient 的 Lamba 表达式。在上面的示例中,我使用要使用此特定 HTTP 客户端调用的第三方 API 的 URL 来设置 BaseAddress 属性。
一旦 HTTP 客户端被注册,我们就可以在我们的控制器和服务中注入 IHttpClientFactory 并调用它的 CreateClient 方法来创建我们想要在我们的代码中使用的特定 HTTP 客户端对象。 CreateClient 方法需要您要创建的 HTTP 客户端的名称,如下所示:
public class HolidaysApiService : IHolidaysApiService
{
private readonly HttpClient client;
public HolidaysApiService(IHttpClientFactory clientFactory)
{
client = clientFactory.CreateClient("PublicHolidaysApi");
}
public async Task<List<HolidayModel>> GetHolidays(string countryCode, int year)
{
var url = string.Format("/api/v2/PublicHolidays/{0}/{1}", year, countryCode);
var result = new List<HolidayModel>();
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<List<HolidayModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
else
{
throw new HttpRequestException(response.ReasonPhrase);
}
return result;
}
}
总结概括
在本文中,我向您概述了 HttpClient,并提供了直接或使用 IHttpClientFactory 创建 HttpClient 对象的示例。我还向您展示了一个使用 HttpClient 调用第三方 Web API 的示例。希望您现在熟悉 HttpClient 对象及其用法,并且可以放心地开始在您的项目中使用它。
.net Api 接口调用 增删改查
.net Api项目搭建内容以前已经说过了,文章链接,这篇文章在已经搭建好项目基础上简单说下如何建立API增删改查接口。
在Models中建立一个实体类:
namespace ApiTest.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
处理数据的接口放在Models中:
namespace ApiTest.Models
{
interface IProductRepository
{
IEnumerable<Product> GetAll();
Product Get(int id);
Product Add(Product item);
void Remove(int id);
bool Update(Product item);
}
}
业务处理的接口实现类也放在Models中:
namespace ApiTest.Models
{
public class ProductRepository:IProductRepository
{
private List<Product> products = new List<Product>();
private int _nextId = 1;
public ProductRepository()
{
products.Add(new Product { Id = 0, Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
products.Add(new Product { Id = 1, Name = "Yo-yo", Category = "Toys", Price = 3.75M });
products.Add(new Product { Id = 2, Name = "Hammer", Category = "Hardware", Price = 16.99M });
}
public IEnumerable<Product> GetAll()
{
return products;
}
public Product Get(int id)
{
return products.Find(p=>p.Id==id);
}
public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId++;
products.Add(item);
return item;
}
public void Remove(int id)
{
products.RemoveAll(p=>p.Id==id);
}
public bool Update(Product item)
{
if(item==null)
{
throw new ArgumentNullException("item");
}
int index = products.FindIndex(p=>p.Id==item.Id);
if (index == -1)
{
return false;
}
products.RemoveAt(index);
products.Add(item);
return true;
}
}
在Controllers中新建ProductController:
//这里路由处理根据http协议
namespace ApiTest.Controllers
{
public class ProductsController : ApiController
{
static readonly IProductRepository repository = new ProductRepository();
//GET: /api/products
public IEnumerable<Product> GetAllProducts()
{
return repository.GetAll();
}
//GET: /api/products/id
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
//GET: /api/products?category=Groceries
public IEnumerable<Product> GetProductsByCategory(string category)
{
return repository.GetAll().Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));
}
//POST: /api/products
public HttpResponseMessage PostProduct(Product item)
{
item = repository.Add(item);
var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);
string uri = Url.Link("DefaultApi", new { id = item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
//PUT: /api/products/id
public void PutProduct(int id, Product product)
{
product.Id = id;
if (!repository.Update(product))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
//Delete: /api/products/id
public void DeleteProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
repository.Remove(id);
}
}
在Views中的Home中修改原有的index文件:
<script src="~/Content/jquery-3.1.1.js"></script>
<div id="body">
<section>
<h2>添加记录</h2>
Name:<input id="name" type="text" /><br />
Category:<input id="category" type="text" />
Price:<input id="price" type="text" /><br />
<input id="addItem" type="button" value="添加" />
</section>
<section>
<br />
<br />
<h2>修改记录</h2>
Id:<input id="id2" type="text" /><br />
Name:<input id="name2" type="text" /><br />
Category:<input id="category2" type="text" />
Price:<input id="price2" type="text" /><br />
<input id="showItem" type="button" value="查询" />
<input id="editItem" type="button" value="修改" />
<input id="removeItem" type="button" value="删除" />
</section>
</div>
<script>
//用于保存用户输入数据
var Product = {
create: function () {
Id: "";
Name: "";
Category: "";
Price: "";
return Product;
}
}
//添加一条记录 请求类型:POST 请求url: /api/Products
//请求到ProductsController.cs中的 public HttpResponseMessage PostProduct(Product item) 方法
$("#addItem").click(function () {
var newProduct = Product.create();
newProduct.Name = $("#name").val();
newProduct.Category = $("#category").val();
newProduct.Price = $("#price").val();
$.ajax({
url: "/api/Products",
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(newProduct),
success: function () {
alert("添加成功!");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
});
//先根据Id查询记录 请求类型:GET 请求url: /api/Products/Id
//请求到ProductsController.cs中的 public Product GetProduct(int id) 方法
$("#showItem").click(function () {
var inputId = $("#id2").val();
$("#name2").val("");
$("#category2").val("");
$("#price2").val("");
$.ajax({
url: "/api/Products/" + inputId,
type: "GET",
contentType: "application/json; charset=urf-8",
success: function (data) {
$("#name2").val(data.Name);
$("#category2").val(data.Category);
$("#price2").val(data.Price);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
});
//修改该Id的记录 请求类型:PUT 请求url: /api/Products/Id
//请求到ProductsController.cs中的 public void PutProduct(int id, Product product) 方法
$("#editItem").click(function () {
var inputId = $("#id2").val();
var newProduct = Product.create();
newProduct.Name = $("#name2").val();
newProduct.Category = $("#category2").val();
newProduct.Price = $("#price2").val();
$.ajax({
url: "/api/Products/" + inputId,
type: "PUT",
data: JSON.stringify(newProduct),
contentType: "application/json; charset=urf-8",
success: function () {
alert("修改成功! ");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
});
//删除输入Id的记录 请求类型:DELETE 请求url: /api/Products/Id
//请求到ProductsController.cs中的 public void DeleteProduct(int id) 方法
$("#removeItem").click(function () {
var inputId = $("#id2").val();
$.ajax({
url: "/api/Products/" + inputId,
type: "DELETE",
contentType: "application/json; charset=uft-8",
success: function (data) {
alert("Id为 " + inputId + " 的记录删除成功!");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
});
</script>
启动项目,进入home的index页面,这里会对Api接口进行请求操作。
mvc 处理json数据:
@{
ViewData["Title"] = "Home Page";
}
<div>
<button id="sumbit" onclick="ajax()">获取</button>
<a id="xinxi"></a><br />
姓名:
<input type="text" id="name" />
♠
密码:
<input type="text" id="password" />
jieguo:
<input type="text" id="xinxi22" />
<div id="xinxi" >33333333333 </div>
</div>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script type="text/javascript" >
function ajax() {
var password = document.getElementById("password").value;
var name = document.getElementById("name").value;
var xixn = JSON.stringify({
Name: name,
Password: password
});
var xhr = new XMLHttpRequest;//创建一个 XMLHttpRequest 对象,XMLHttpRequest是实现ajax的基础
xhr.open("POST", "/Hello/Login", true);//请求方式为"Post","/Home/Index"为服务器地址(在MVC这里就是控制器地址+方法名),true表示选择异步
xhr.setRequestHeader("Content-type", "application/json");//设置请求参数类型
xhr.send(xixn);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var s = xhr.responseText;
alert(s);
document.getElementById("xinxi").innerHTML = JSON.parse(s).result;
} else {
alert(xhr.status + ":" + xhr.readyState+ ":" + xhr.responseText);
}
}
}
</script>
后台代码:
[HttpPost]
public IActionResult Login([FromBody] Model7 model)
{
if (model != null)
{
string Name = model.Name;
string password = model.Password;
return Json(new { result = "my:" + Name + "is:" + password });
}
else
{
return Json(new { result = "it Is Null" });
}
}
public class Model7
{
public string Name { get; set; }
public string Password { get; set; }
}