.Net之接口小知识

目的

通过一个简单的项目,在原来的文章基础上完善一下常用的几种WebApi编写方式以及请求方式,一方面是用于给我一个前端朋友用来学习调用接口,另一方面让我测试HttpClient的一些效果。

本文示例代码环境:vs2022、net6

准备

新创建了一个.Net WebAPI程序,安装组件

<ItemGroup>     <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" />     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.1" />     <PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.3.1" /> </ItemGroup> 

ConfigureServices配置NewtonsoftJson以及Automapper和操作数据库代码(为了省事,删除了一些不影响当前效果的代码)

public void ConfigureServices(IServiceCollection services) { 	services.AddControllers().AddNewtonsoftJson();      services.AddEndpointsApiExplorer(); 	services.AddSwaggerGen(c => 	{ 		c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyWebApi", Version = "v1" }); 	}); 	 	//注入AutoMapper 	services.AddAutoMapper(Assembly.GetExecutingAssembly().DefinedTypes.Where(t => typeof(Profile).GetTypeInfo() 	.IsAssignableFrom(t.AsType())).Select(t => t.AsType()).ToArray()); } 

注意:在Net core3.0以后,微软移除了Newtonsoft.Json,而使用了System.Text.Json,所以依赖于Newtonsoft.Json的组件将不可用,需要安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包

因为仅仅作为演示,所以我只是新增一个控制器,里面包含了get、post、put、patch、delete几种类型的接口。这里先不贴代码,一点一点看。通过一个用户的添加、修改、删除作为一个演示的流程。

记得配置允许跨域请求,要不js请求会因为跨域问题而报错。详情看此处

数据来源就是控制器里面的一个静态变量,格式如下

public class UserDto {     public long UserId { get; set; }      public string Name { get; set; }      public string Sex { get; set; } } 

静态变量如下

private static readonly List<UserDto> _userDtoList = Enumerable.Range(0, 100)         .Select(t => new UserDto         {             Name = "张三" + t,             Sex = "男",             UserId = 6974150586715897857 + t         }).ToList(); 

后端请求的方法我使用的是HttpClient,并且做成了一个公共类,部分需要用到的如下

public class HttpClientHelper: IHttpHelper {     private readonly System.Net.Http.HttpClient _client;      /// <summary>     /// 构造函数     /// </summary>     /// <param name="httpClientFactory"></param>     public HttpClientHelper(IHttpClientFactory httpClientFactory)     {         _client = httpClientFactory.CreateClient();     }      private void VerifyParam(string url, string jwtToken, IDictionary<string, string> headers)     {         _client.DefaultRequestHeaders.Clear();         if (string.IsNullOrWhiteSpace(url))         {             throw new ArgumentNullException("url不能为null");         }         if (!string.IsNullOrWhiteSpace(jwtToken))         {             _client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");         }         if (headers?.Count > 0)         {             foreach (var (key, value) in headers)             {                 _client.DefaultRequestHeaders.Add(key, value);             }         }     }      private static async Task<T> ConvertResponseResult<T>(HttpResponseMessage httpResponse)     {         //确保成功完成,不是成功就返回具体错误信息         httpResponse.EnsureSuccessStatusCode();         var resStr = await httpResponse.Content.ReadAsStringAsync();         if (typeof(T) == typeof(string))             return (T)Convert.ChangeType(resStr, typeof(string));          return JsonConvert.DeserializeObject<T>(resStr);     } } 

操作

请求头传递token只是为了演示请求头传递参数的写法,token为伪值

GET

从web服务检索数据。传递参数的本质是url字符串拼接,Request-Head头部传递,Request-Body中不能传递(严格点说不建议,因为我使用Apifox等工具可以在body中传值,swagger会提示 Request with GET/HEAD method cannot have body)

Query格式

编写用户id查询用户信息接口

[HttpGet("user/details")] public UserDto GetUserDetails(long userId) {     if (!_userDtoList.Any(t => t.UserId == userId))         throw new ParameterException("未找到用户标识");     return _userDtoList.Find(t => t.UserId == userId); } 

前端请求

$(function () {     $.ajax({         type: "get",         url: "http://localhost:5000/api/HttpSample/user/details?userId=6974150586715897857",         headers: { "Authorization": "Bearer 123456" },         contentType: "application/json",         success: function (data, status) {             if (status == "success") {                 console.log(JSON.stringify(data));             }         }     });      var postdata = { userId: "6974150586715897857" };     $.ajax({         type: "get",         headers:{"Authorization":"Bearer 123456"},         url: "http://localhost:5000/api/HttpSample/user/details",         data: postdata,         success: function (data, status) {              if (status == "success") {                 console.log(JSON.stringify(data));             }           }     }); }); 

后端请求

var token = "123456";//此处token是伪值 var result = await _httpHelper.GetAsync<ResultModel<UserDto>>("http://localhost:5000/api/HttpSample/user/details?userId=6974150586715897857", token); 

这里的_httpHelper是注入的IHttpHelper(下面其他的方法一样),对应的GetAsync为

public async Task<T> GetAsync<T>(string url, string jwtToken = "", IDictionary<string, string> headers = null) {     VerifyParam(url, jwtToken, headers);      var response = await _client.GetAsync(url).ConfigureAwait(false);     return await ConvertResponseResult<T>(response).ConfigureAwait(false); } 

接口工具请求

url:http://localhost:5000/api/HttpSample/user/details?userId=6974150586715897857

并且再请求头增加:Authorization,值为Bearer xxxx

返回结果如下

.Net之接口小知识

POST

在web服务上创建新的数据项。约定用于向服务端提交数据操作,请求时候参数放在参数FromBody传递

Json格式

演示添加用户操作

请求类

public class UserDto {     public long UserId { get; set; }      public string Name { get; set; }      public string Sex { get; set; } } 

接口代码示例

[HttpPost("user/add")] public bool Add([FromBody] UserDto request) {     if (_userDtoList.Any(t => t.UserId == request.UserId))         throw new ParameterException("用户标识已经存在");     Console.WriteLine(DateTime.Now + "   " + HttpContext.Request.Headers["Authorization"].FirstOrDefault());     _userDtoList.Add(request);     return true; } 

前端请求

$(function () {     var param = { userId: "8974150586715897867", name: "老八", sex: "女" };     $.ajax({         type: "post",         dataType: 'json',         contentType: "application/json",         headers: { "Authorization": "Bearer 123456" },         url: "http://localhost:5000/api/HttpSample/user/add",         data: JSON.stringify(param),         success: function (data) {             if (status == "success") {                 console.log(JSON.stringify(data));             }         }     }); }); 

后端请求

var token = "123456";//此处token是伪值 var url = "http://localhost:5000/api/HttpSample/user/add";  var usedto = new UserDto {     UserId = 123456,     Name = "李四",     Sex = "女" };  var result = await _httpHelper.PostAsync<ResultModel<bool>>(url, usedto, token);   public async Task<T> PostAsync<T>(string url, object data, string jwtToken = "", IDictionary<string, string> headers = null) {     VerifyParam(url, jwtToken, headers);     var jsonData = data is string ? data.ToString() : JsonConvert.SerializeObject(data);     using var content = new StringContent(jsonData ?? string.Empty, Encoding.UTF8, "application/json");     var response = await _client.PostAsync(url, content).ConfigureAwait(false);     return await ConvertResponseResult<T>(response).ConfigureAwait(false); } 

接口工具请求

传递参数格式为json格式,请求头部默认添加:"Content-Type", "application/json"

.Net之接口小知识

x-www-form-unlencoded格式

更新用户姓名

[HttpPost("user/updatename")] public bool UpdateName([FromForm] long userId, [FromForm] string name) {     var entity = _userDtoList.Find(t => t.UserId == userId);     if (entity is null)         throw new ParameterException("用户标识不存在");      entity.Name = name;      return true; } 

前端请求

$(function () {     var postdata = { userId: "6974150586715897857", name: "赵六" };     $.ajax({         type: "post",         headers: { "Authorization": "Bearer 123456" },         url: "http://localhost:5000/api/HttpSample/user/updatename",         data: postdata,         success: function (data, status) {             if (status == "success") {                 console.log(JSON.stringify(data));             }         }     }); }); 

后端请求

var token = "123456";//此处token是伪值 var url = "http://localhost:5000/api/HttpSample/user/updatename"; var dic = new Dictionary<string, string> {     { "userId","6974150586715897857"},     { "name","王五"} }; var result = await _httpHelper.PostFormDataAsync<ResultModel<bool>>(url, dic, token);   public async Task<T> PostFormDataAsync<T>(string url, Dictionary<string, string> data, string jwtToken = "", IDictionary<string, string> headers = null) {     VerifyParam(url, jwtToken, headers);     var httpContent = new FormUrlEncodedContent(data);     var response = await _client.PostAsync(url, httpContent).ConfigureAwait(false);     return await ConvertResponseResult<T>(response).ConfigureAwait(false); } 

接口工具请求

选择post请求,参数在Body,然后选择x-www-form-unlencoded格式。

.Net之接口小知识

Form-data格式

模拟上传用户头像操作

[HttpPost("user/uploadImg")] public string Upload([FromForm] IFormFile img, [FromForm] long userId) {     if (img is null)         throw new ParameterException("用户头像不能为null");      Console.WriteLine(HttpContext.Request.Headers["Authorization"].FirstOrDefault());     var entity = _userDtoList.Find(t => t.UserId == userId);     if (entity is null)         throw new ParameterException("用户标识不存在");      return img.FileName; } 

注意:当你上传大于30000000字节长度的文件时候,需要修改上传文件的默认限制

前端请求

$(function () {     $("#tijiao").click(function () {         //logoimg是<input type="file" id="logoimg"" />         var files = $("#logoimg").prop('files'); //获取到文件列表          var formData = new FormData();         formData.append("userId", "6974150586715897857");         formData.append("img", files[0], "1122.jpg");//图片文件流          console.log(formData);         $.ajax({             type: 'post',             url: "http://localhost:5000/api/HttpSample/user/uploadImg",             headers: {                 "Authorization": "Bearer 123456"             },             mimeType: "multipart/form-data",             processData: false,             contentType: false,             data: formData,             success: function (data) {                 //后端Httpclient请求成功后返回过来的结果                 console.log(data);             }         });     }); }); 

后端请求

var url = "http://localhost:5000/api/HttpSample/user/uploadImg";  var formData = new MultipartFormDataContent();  var bytes = System.IO.File.ReadAllBytes("D:\Downloads\11111.jpg"); var byteContent = new ByteArrayContent(bytes); byteContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") {     Name = "img",     FileName = "111.jpg" }; formData.Add(byteContent);  // 写法一 formData.Add(new StringContent("6974150586715897857"), "userId");  // 写法二 var byteContent2 = new ByteArrayContent(Encoding.UTF8.GetBytes("天气")); byteContent2.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") {     Name = "name", }; formData.Add(byteContent2);  var headerDic = new Dictionary<string, string> { 	{ "Authorization","Bearer 123456"}, };  var result = await _httpHelper.PostFormDataAsync<ResultModel<string>>(url, formData, headerDic);   public async Task<T> PostFormDataAsync<T>(string url, MultipartFormDataContent data, IDictionary<string, string> headers = null) {     VerifyParam(url, "", headers);     var result = await _client.PostAsync(url, data).ConfigureAwait(false);     return await ConvertResponseResult<T>(result); } 

接口工具请求

选择Body=>form-data

.Net之接口小知识

PUT

更新web服务上的数据项。

Json格式

更新用户信息

[HttpPut("user/update")] public bool Update(UserDto userDto) {     if (userDto is null)         throw new ParameterException("参数不能为空");          Console.WriteLine(DateTime.Now + "    " + HttpContext.Request.Headers["Authorization"].FirstOrDefault());         var currUser = _userDtoList.Find(t => t.UserId == userDto.UserId);     if (currUser is null)         throw new ParameterException("用户标识不存在");      currUser.Name = userDto.Name;     currUser.Sex = userDto.Sex;     return true; } 

前端请求

$(function () {     var param = { userId: "6974150586715897859", name: "老八", sex: "女" };     $.ajax({         type: "put",         dataType: 'json',         contentType: "application/json",         headers: { "Authorization": "Bearer 123456" },         url: "http://localhost:5000/api/HttpSample/user/update",         data: JSON.stringify(param),         success: function (data, status) {             if (status == "success") {                 console.log(JSON.stringify(data));             }         }     }); }); 

后端请求

var token = "123456";//此处token是伪值  var usedto = new UserDto {     UserId = 6974150586715897859,     Name = "老八",     Sex = "女" };  var url = "http://localhost:5000/api/HttpSample/user/update";  var result = await _httpHelper.PutAsync<ResultModel<bool>>(url, usedto, token); return JsonConvert.SerializeObject(result);   public async Task<T> PutAsync<T>(string url, object data, string jwtToken = "", IDictionary<string, string> headers = null) {     VerifyParam(url, jwtToken, headers);     var jsonData = data is string ? data.ToString() : JsonConvert.SerializeObject(data);     using var content = new StringContent(jsonData ?? string.Empty, Encoding.UTF8, "application/json");     var response = await _client.PutAsync(url, content).ConfigureAwait(false);     return await ConvertResponseResult<T>(response).ConfigureAwait(false); } 

接口工具请求

URL:http://localhost:5000/api/HttpSample/user/update

参数传递:Body=>json

.Net之接口小知识

DELETE

删除web服务上的数据项。

Query格式

删除用户信息

[HttpDelete("user")] public bool Delete(long userId) {     var entity = _userDtoList.Find(t => t.UserId == userId);     if (entity is null)         throw new ParameterException("用户标识不存在");      Console.WriteLine(DateTime.Now + "    " + HttpContext.Request.Headers["Authorization"].FirstOrDefault());     _userDtoList.Remove(entity);     return true; } 

前端请求

$(function () {     $.ajax({         type: "DELETE",         url: "http://localhost:5000/api/HttpSample/user?userId=6974150586715897861",         headers: { "Authorization": "Bearer 123456" },         success: function (data, status) {             if (status == "success") {                 console.log(JSON.stringify(data));             }         }     }); }); 

后端请求

var token = "123456";//此处token是伪值 var url = "http://localhost:5000/api/HttpSample/user?userId=6974150586715897862";  var result = await _httpHelper.DeleteAsync<ResultModel<bool>>(url, token);  public async Task<T> DeleteAsync<T>(string url, string jwtToken = "", IDictionary<string, string> headers = null) {     VerifyParam(url, jwtToken, headers);     var response = await _client.DeleteAsync(url).ConfigureAwait(false);     return await ConvertResponseResult<T>(response).ConfigureAwait(false); } 

接口工具请求

URL:http://localhost:5000/api/HttpSample/user?userId=6974150586715897859

.Net之接口小知识

Patch

通过描述有关如何修改项的一组说明,更新web服务上的数据项。

请求格式如下:

[{"op" : "replace", "path" : "/PassWord", "value" : "222222"}]

op属性指示操作的类型,path属性指示要更新的元素,value属性提供新值。

add:添加属性或数组元素。 对于现有属性:设置值。

remove:删除属性或数组元素。

replace:替换操作

为了支持该请求方式,需要安装nuget包Microsoft.AspNetCore.Mvc.NewtonsoftJson。

参考文档:https://docs.microsoft.com/zh-cn/aspnet/core/web-api/jsonpatch?view=aspnetcore-6.0

Json格式

在此用于更新数据

[HttpPatch("user/update2/{userId}")] public UserDto Update2([FromRoute] long userId, JsonPatchDocument<UserDto> jsonPatch, [FromServices] IMapper mapper) {     var entity = _userDtoList.Find(t => t.UserId == userId);     if (entity is null)         throw new ParameterException("用户标识无效");      var dto = mapper.Map<UserDto>(entity);     jsonPatch.ApplyTo(dto, ModelState);      var user = _userDtoList.Find(t => t.UserId == userId);     mapper.Map(dto, user);     return user; } 

前端请求

演示根据用户id去更新用户的姓名

$(function () {     var par = [{ "op": "replace", "path": "/name", "value": "老六" }];     $.ajax({         type: "Patch",         url: "http://localhost:5000/api/HttpSample/user/update2/6974150586715897857",         headers: { "Authorization": "Bearer 123456" },         contentType: "application/json",         data: JSON.stringify(par),         success: function (result) {             console.log(result);         }     }); }); 

后端请求

var token = "123456";//此处token是伪值 var url = "http://localhost:5000/api/HttpSample/user/update2/6974150586715897859"; var content = "[{"op":"replace","path":"/name","value":"小七七"}]"; var result = await _httpHelper.PatchAsync<ResultModel<UserDto>>(url, content, token);  public async Task<T> PatchAsync<T>(string url, object data, string jwtToken = "", IDictionary<string, string> headers = null) {     VerifyParam(url, jwtToken, headers);     var jsonData = data is string ? data.ToString() : JsonConvert.SerializeObject(data);     using var content = new StringContent(jsonData ?? string.Empty, Encoding.UTF8, "application/json");     var response = await _client.PatchAsync(url, content).ConfigureAwait(false);     return await ConvertResponseResult<T>(response).ConfigureAwait(false); } 

接口工具请求

参数传递:Body=>json

.Net之接口小知识

发表评论

评论已关闭。

相关文章