本文只對api介面,header請求參數進行簡單驗證,起到拋磚引玉使用,需要深入驗證,請自行擴展 項目目錄結構如圖 中間件類 using ApiMiddleware.Common.DataEnityModel; using ApiMiddleware.Common.DbContext; using ...
本文只對api介面,header請求參數進行簡單驗證,起到拋磚引玉使用,需要深入驗證,請自行擴展
項目目錄結構如圖
- 中間件類
using ApiMiddleware.Common.DataEnityModel; using ApiMiddleware.Common.DbContext; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiMiddleware.Middleware { public class RequestHeaderVerificationMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; /// <summary> /// 計時器 /// </summary> private Stopwatch _stopwatch; private const string RESPONSE_HEADER_RESPONSE_TIME = "X-Response-Time-ms"; public RequestHeaderVerificationMiddleware(RequestDelegate next, ILogger<RequestHeaderVerificationMiddleware> logger) { _next = next; _logger = logger; } public async Task Invoke(HttpContext context, MySqlMasterDbContext masterDbContext) { _stopwatch = new Stopwatch(); _stopwatch.Start(); _logger.LogError($"Handling request: {context.Request.Path}"); if (!context.Request.Headers.TryGetValue("request_id", out StringValues request_id) || string.IsNullOrEmpty(request_id)) { await HandleMessage(context, JsonConvert.SerializeObject(new { msg = "request_id不可為空", request_id = request_id })); goto step; } if (!context.Request.Headers.TryGetValue("uname", out StringValues uname) || string.IsNullOrEmpty(uname)) { await HandleMessage(context, JsonConvert.SerializeObject(new { msg = "名稱不可為空", request_id = request_id, uname = uname })); goto step; } var stu = new student { id = request_id, stu_name = uname, createtime = DateTime.Now, updatetime = DateTime.Now }; var model = masterDbContext.student.FirstOrDefault(m => m.id == request_id); if (model == null) masterDbContext.Add(stu); else { model.stu_name = uname; model.updatetime = DateTime.Now; masterDbContext.Update(model); } masterDbContext.SaveChanges(); context.Response.OnStarting(() => { // Stop the timer information and calculate the time _stopwatch.Stop(); var responseTimeForCompleteRequest = _stopwatch.ElapsedMilliseconds; // Add the Response time information in the Response headers. context.Response.Headers[RESPONSE_HEADER_RESPONSE_TIME] = responseTimeForCompleteRequest.ToString(); return Task.CompletedTask; }); step: if (!context.Response.HasStarted) { await _next(context); } } /// <summary> /// 錯誤信息或驗證信息處理方法 /// </summary> /// <param name="context"></param> /// <param name="msg"></param> /// <returns></returns> private async Task HandleMessage(HttpContext context, string msg) { context.Response.ContentType = "text/json;charset=utf-8;"; //瀏覽器在開發環境顯示詳細錯誤信息,其他環境隱藏錯誤信息 await context.Response.WriteAsync(msg); } } }
using Microsoft.AspNetCore.Builder; namespace ApiMiddleware.Middleware { public static class MyMiddlewareExtensions { public static void UseMyMiddleware(this IApplicationBuilder builder) { builder.UseMiddleware<RequestHeaderVerificationMiddleware>(); } } }
- 資料庫操作類MySqlMasterDbContext
using ApiMiddleware.Common.DataEnityModel; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ApiMiddleware.Common.DbContext { public class MySqlMasterDbContext : Microsoft.EntityFrameworkCore.DbContext { private string _conn; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!string.IsNullOrEmpty(_conn)) { optionsBuilder.UseMySQL(_conn); } base.OnConfiguring(optionsBuilder); } public MySqlMasterDbContext(DbContextOptions<MySqlMasterDbContext> options) : base(options) { Database.EnsureCreated(); } public MySqlMasterDbContext(string conn) { _conn = conn; } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); } public DbSet<student> student { get; set; } } }
- 在Startup中註冊中間件
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ApiMiddleware.Common.DbContext; using ApiMiddleware.Middleware; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace ApiMiddleware { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var identityConn = "Server=localhost;Database=business;Uid=root;Pwd=root;"; services.AddDbContext<MySqlMasterDbContext>(options => options.UseMySQL(identityConn)); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseMyMiddleware();//註冊中間件 app.UseHttpsRedirection(); app.UseMvc(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ApiMiddleware.Common.DataEnityModel; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; namespace ApiMiddleware.Controllers { [Route("api/[controller]")] [ApiController] public class StuController : ControllerBase { [HttpPost("stuinfo")] public ActionResult<string> AddStu([FromBody]StudentExternal info) { return JsonConvert.SerializeObject(new { result="Success",Data=info.data}); } } }
- 請求實例測試,註意請求頭不要帶漢字,否則報錯
- 如請求頭帶漢字,則報如下提示