这篇文章讲解一下微信小程序js调用.net core webapi 返回值中有雪花算法int64类型ID数据丢失(最后两位数后变成0)的解决方案
这里我们是通过.net core中间件,拦截Request.body 、Reposne.body并修改他们, 本来想作filter过滤器实现的 但是发现过滤器执行顺序要晚于中间件 而且json已经给action参数赋值了 所以当入参是字符串 而接收参数是int类型时,还没有进入filter就已经出现异常了
所以我们选择中间件实现
这里我提供一下关键代码
讲一下我的项目情况
1、版本:.net core3.0
2、部署在了iis上
第一步、创建中间件,并写相关代码
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace CountingCardService { public class ResultMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public ResultMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<ResultMiddleware>(); } public async Task InvokeAsync(HttpContext context) { try { MemoryStream ms1 = null; StreamWriter writer = null; HttpRequest request = context.Request; // 获取请求body内容 if (request.Method.ToLower().Equals("post")) { // 启用倒带功能,就可以让 Request.Body 可以再次读取 request.EnableBuffering(); Stream stream = request.Body; //获取到body值 string bodyAsText = await new StreamReader(request.Body).ReadToEndAsync(); //修改body值(这块代码可以根据自己业务自己写) bodyAsText = Regex.Replace(bodyAsText, "(\":\")([0-9]{16,19})(\",)", "\":$2,"); //放到流中回填回去 ms1 = new MemoryStream(); writer = new StreamWriter(ms1); writer.Write(bodyAsText); writer.Flush(); request.Body = ms1; request.Body.Position = 0; } //获取到Response.body内容 using (var ms = new MemoryStream()) { var orgBodyStream = context.Response.Body; context.Response.Body = ms; //context.Response.ContentType = "multipart/form-data"; //执行controller中正常逻辑代码 await _next(context); using (var sr = new StreamReader(ms)) { ms.Seek(0, SeekOrigin.Begin); //得到Action的返回值 var responseJsonResult = sr.ReadToEnd(); ms.Seek(0, SeekOrigin.Begin); //如下代码若不注释则会显示Action的返回值 这里做了注释 则清空Action传过来的值 // await ms.CopyToAsync(orgBodyStream); //修改返回值,这块代码可以根据自己业务自己写 responseJsonResult = Regex.Replace(responseJsonResult, "(\":)([0-9]{16,})(,)", "$1\"$2\"$3"); var alterResult = responseJsonResult; context.Response.Body = orgBodyStream; //显示修改后的数据 await context.Response.WriteAsync(alterResult, Encoding.UTF8); } } if (writer != null) { writer.Close(); writer.Dispose(); } if (ms1 != null) { ms1.Close(); ms1.Dispose(); } } catch (Exception ex) { throw ex; } } } }
第二步 修改Startup.cs文件
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CountingCardServiceBLL; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace CountingCardService { 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.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); //添加我们刚刚的中间件 app.UseResult(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }