[toc] # MiniMalAPi - 最小的api, 請求都寫在Program.cs中, 可以做微服務 ## Demo ### Program.cs ```c# //基本請求 app.MapGet("/GetTest", () => new { result = "123", code = 20 ...
目錄
MiniMalAPi
- 最小的api, 請求都寫在Program.cs中, 可以做微服務
Demo
Program.cs
//基本請求
app.MapGet("/GetTest", () => new { result = "123", code = 200 }).WithTags("General Request");
app.MapPost("/PostTest", () => new { result = "123", code = 200 }).WithTags("General Request");
app.MapPut("/PutTest", () => new { result = "123", code = 200 }).WithTags("General Request");
app.MapDelete("DeletePut", () => new { result = "123", code = 200 }).WithTags("General Request");
//註入
app.MapGet("/GetTestIoc", (IStudent student,IWrite pen) => student.Calligraphy(pen)).WithTags("Ioc");
app.MapGet("/GetTestIocById", (IStudent student,IWrite pen,int? id) => student.Calligraphy(pen)).WithTags("Ioc");
app.MapPost("/GetTestIocByObject", (IStudent student,IWrite pen,Result result) => student.Calligraphy(pen)).WithTags("Ioc");
Swagger
文檔+信息
Program.cs
builder.Services.AddSwaggerGen(setup =>
{
setup.SwaggerDoc("V1", new()
{
Title = "qfccc",
Version = "V1",
Description = "qfccc description",
});
});
app.UseSwaggerUI(setup =>
{
setup.SwaggerEndpoint("/swagger/V1/swagger.json", "V1");
});
API版本控制
- 該例子僅供參考
ApiVersion.cs
namespace WebApiDemo.VersionControl
{
public class ApiVersion
{
public static string? Version1;
public static string? Version2;
public static string? Version3;
public static string? Version4;
public static string? Version5;
}
}
Version1Controller.cs
- 這裡其他版本api 修改ApiVersion.Version1即可
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WebApiDemo.VersionControl;
namespace WebApiDemo.Controllers
{
[ApiExplorerSettings(GroupName = nameof(ApiVersion.Version1))]
[Route($"api/[controller]/[action]/api.{nameof(ApiVersion.Version1)}")]
[ApiController]
public class Version1Controller : ControllerBase
{
[HttpGet]
public IActionResult GetString() => new JsonResult(new { result = "Success" });
[HttpPost]
public IActionResult PostString() => new JsonResult(new { result = "Success" });
[HttpPut]
public IActionResult PutString() => new JsonResult(new { result = "Success" });
[HttpDelete]
public IActionResult DeleteString() => new JsonResult(new { result = "Success" });
}
}
Program.cs
builder.Services.AddSwaggerGen(setup =>
{
foreach (var field in typeof(ApiVersion).GetFields())
{
setup.SwaggerDoc(field.Name, new()
{
Title = "qfccc",
Version = field.Name,
Description = $"qfccc api {field.Name}",
});
}
});
app.UseSwaggerUI(setup =>
{
foreach (var field in typeof(ApiVersion).GetFields())
{
setup.SwaggerEndpoint($"/swagger/{field.Name}/swagger.json", field.Name);
}
});
生成註釋
- 項目點擊右鍵 -> 屬性 -> 輸出 -> 勾選(文檔文件)
- 在AddSwaggerGen中間件添加下方代碼
string? basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
if(basePath is not null)
{
string apiPath = Path.Combine(basePath, "項目名稱.xml");
setup.IncludeXmlComments(apiPath);
}
解決跨域
- 調用方調用自己後臺,然後用後臺請求目標介面解決跨域
- 伺服器支持跨域請求
- 在Action中添加這行代碼:
- HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
- 使用ActionFilter 實現過濾器,代碼與上方一致, 然後在Program.cs 文件中全局註冊一下該過濾器,但是不支持Post,Put,Delete這種請求
- 所有請求都支持跨域可以在Program.cs中增加下方代碼:
builder.Services.AddCors( setup =>
{
setup.AddPolicy("SolveCrossOrigin", policy =>
{
policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();
});
});
app.UseCors("SolveCrossOrigin");
.Net 後臺請求封裝
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace NET5WebApplication.Utility
{
public static class HttpClientHelper
{
/// <summary>
/// 發起POST同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static string HttpPost(string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
postData = postData ?? "";
using (HttpClient client = new System.Net.Http.HttpClient())
{
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
{
if (contentType != null)
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
}
/// <summary>
/// 發起POST非同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static async Task<string> HttpPostAsync(string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
postData = postData ?? "";
using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient())
{
client.Timeout = new TimeSpan(0, 0, timeOut);
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
{
if (contentType != null)
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
HttpResponseMessage response = await client.PostAsync(url, httpContent);
return await response.Content.ReadAsStringAsync();
}
}
}
/// <summary>
/// 發起GET同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static string HttpGet(string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
using (HttpClient client = new HttpClient())
{
if (contentType != null)
client.DefaultRequestHeaders.Add("ContentType", contentType);
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
HttpResponseMessage response = client.GetAsync(url).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
/// <summary>
/// 發起GET非同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static async Task<string> HttpGetAsync(string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient())
{
if (contentType != null)
client.DefaultRequestHeaders.Add("ContentType", contentType);
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
HttpResponseMessage response = await client.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
}
/// <summary>
/// 發起POST同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static T HttpPost<T>(string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
return HttpPost(url, postData, contentType, timeOut, headers).ToEntity<T>();
}
/// <summary>
/// 發起POST非同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static async Task<T> HttpPostAsync<T>(string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
var res = await HttpPostAsync(url, postData, contentType, timeOut, headers);
return res.ToEntity<T>();
}
/// <summary>
/// 發起GET同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static T HttpGet<T>(string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
return HttpGet(url, contentType, headers).ToEntity<T>();
}
/// <summary>
/// 發起GET非同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static async Task<T> HttpGetAsync<T>(string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
var res = await HttpGetAsync(url, contentType, headers);
return res.ToEntity<T>();
}
}
public static class HttpExtension
{
/// <summary>
/// 發起GET同步請求
/// </summary>
/// <param name="client"></param>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static string HttpGet(this System.Net.Http.HttpClient client, string url, string contentType = "application/json",
Dictionary<string, string> headers = null)
{
if (contentType != null)
client.DefaultRequestHeaders.Add("ContentType", contentType);
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
HttpResponseMessage response = client.GetAsync(url).Result;
return response.Content.ReadAsStringAsync().Result;
}
/// <summary>
/// 發起GET非同步請求
/// </summary>
/// <param name="client"></param>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static async Task<string> HttpGetAsync(this System.Net.Http.HttpClient client, string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
if (contentType != null)
client.DefaultRequestHeaders.Add("ContentType", contentType);
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
HttpResponseMessage response = await client.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
/// <summary>
/// 發起POST同步請求
/// </summary>
/// <param name="client"></param>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="timeOut"></param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static string HttpPost(this System.Net.Http.HttpClient client, string url, string postData = null,
string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
postData = postData ?? "";
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
{
if (contentType != null)
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
/// <summary>
/// 發起POST非同步請求
/// </summary>
/// <param name="client"></param>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static async Task<string> HttpPostAsync(this System.Net.Http.HttpClient client, string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
postData = postData ?? "";
client.Timeout = new TimeSpan(0, 0, timeOut);
if (headers != null)
{
foreach (var header in headers)
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
{
if (contentType != null)
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
HttpResponseMessage response = await client.PostAsync(url, httpContent);
return await response.Content.ReadAsStringAsync();
}
}
/// <summary>
/// 發起POST同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static T HttpPost<T>(this System.Net.Http.HttpClient client, string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
return client.HttpPost(url, postData, contentType, timeOut, headers).ToEntity<T>();
}
/// <summary>
/// 發起POST非同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息頭</param>
/// <returns></returns>
public static async Task<T> HttpPostAsync<T>(this System.Net.Http.HttpClient client, string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
{
var res = await client.HttpPostAsync(url, postData, contentType, timeOut, headers);
return res.ToEntity<T>();
}
/// <summary>
/// 發起GET同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static T HttpGet<T>(this System.Net.Http.HttpClient client, string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
return client.HttpGet(url, contentType, headers).ToEntity<T>();
}
/// <summary>
/// 發起GET非同步請求
/// </summary>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static async Task<T> HttpGetAsync<T>(this System.Net.Http.HttpClient client, string url, string contentType = "application/json", Dictionary<string, string> headers = null)
{
var res = await client.HttpGetAsync(url, contentType, headers);
return res.ToEntity<T>();
}
}
public static class JsonExtends
{
public static T ToEntity<T>(this string val)
{
return JsonConvert.DeserializeObject<T>(val);
}
public static string ToJson<T>(this T entity, Formatting formatting = Formatting.None)
{
return JsonConvert.SerializeObject(entity, formatting);
}
}
}
返回數據壓縮
- 在Program.cs中添加下麵代碼
預設壓縮
builder.Services.AddResponseCompression();
app.UseResponseCompression();
Gzip壓縮
builder.Services.AddResponseCompression(config =>
{
config.Providers.Add<GzipCompressionProvider>();
});
builder.Services.Configure<GzipCompressionProviderOptions>(config =>
{
config.Level = CompressionLevel.SmallestSize;
});
緩存
介面緩存
- 使用特性或者直接在返回頭中添加Cache-Control效果一樣
[HttpGet]
[ResponseCache(Duration = 600)]
public IActionResult GetString() => new JsonResult(new { result = "Success" });
[HttpGet]
public IActionResult GetStringEx()
{
HttpContext.Response.Headers.Add("Cache-Control", "public,max-age=600");
return new JsonResult(new { result = "Success" });
}
靜態文件緩存
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = Prepare =>
{
Prepare.Context.Response.Headers.Add(HeaderNames.CacheControl, "public,max-age=600");
}
});