本文只对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; ////// 计时器 /// private Stopwatch _stopwatch; private const string RESPONSE_HEADER_RESPONSE_TIME = "X-Response-Time-ms"; public RequestHeaderVerificationMiddleware(RequestDelegate next, ILogger 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); } } /// /// 错误信息或验证信息处理方法 /// /// /// /// 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(); } } }
- 数据库操作类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(DbContextOptionsoptions) : base(options) { Database.EnsureCreated(); } public MySqlMasterDbContext(string conn) { _conn = conn; } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); } public DbSet 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(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}); } } }
- 请求实例测试,注意请求头不要带汉字,否则报错
- 如请求头带汉字,则报如下提示