如何在ASP.NET Core 8 Web API中接收带前导零的数字XID?
解决ASP.NET Core 8 Web API兼容带前导零XID的方案
核心思路
由于无法修改现有数据契约(xid仍需保持long类型),且要同时兼容普通数字型XID(如12345)和带前导零的字符串型XID(如"06789"),必须在JSON解析环节之前拦截原始请求内容,将非法的带前导零格式xid转换为合法数字格式,再传递给后续的模型绑定流程。
具体实现方案
1. 自定义请求预处理中间件
通过中间件拦截目标端点的POST请求,读取并修改原始JSON中的xid字段,再重新封装请求体传入后续管道。
public class XidPreprocessingMiddleware { private readonly RequestDelegate _next; public XidPreprocessingMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // 仅处理SendMessage端点的POST请求 if (context.Request.Path.StartsWithSegments("/api/SendMessage") && context.Request.Method == HttpMethods.Post) { // 开启请求体缓冲,允许多次读取 context.Request.EnableBuffering(); using var reader = new StreamReader(context.Request.Body, leaveOpen: true); var rawJson = await reader.ReadToEndAsync(); // 重置流位置,避免后续环节读取失败 context.Request.Body.Position = 0; // 处理xid字段格式 var processedJson = FixXidFormat(rawJson); // 替换为处理后的请求体 var modifiedStream = new MemoryStream(Encoding.UTF8.GetBytes(processedJson)); context.Request.Body = modifiedStream; context.Request.ContentLength = modifiedStream.Length; } await _next(context); } private string FixXidFormat(string rawJson) { // 处理字符串类型的带前导零xid,转为纯数字 var processed = Regex.Replace(rawJson, "\"xid\":\"0*(\\d+)\"", "\"xid\":$1"); // 处理非法的带前导零数字xid,去掉前导零(原始JSON中数字带前导零属于非法格式) processed = Regex.Replace(processed, "\"xid\":0+(\\d+)", "\"xid\":$1"); // 处理全零场景:如"0000"转为0 processed = Regex.Replace(processed, "\"xid\":\"0+\"", "\"xid\":0"); processed = Regex.Replace(processed, "\"xid\":0+", "\"xid\":0"); return processed; } } // 扩展方法方便注册中间件 public static class XidPreprocessingMiddlewareExtensions { public static IApplicationBuilder UseXidPreprocessing(this IApplicationBuilder builder) { return builder.UseMiddleware<XidPreprocessingMiddleware>(); } }
2. 注册中间件
在Program.cs中,将该中间件注册在路由中间件之前,确保请求体在被MVC解析前完成处理:
var builder = WebApplication.CreateBuilder(args); // 添加常规服务 builder.Services.AddControllers(); var app = builder.Build(); // 注册XID预处理中间件 app.UseXidPreprocessing(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 验证覆盖场景
- 非法请求
{"xid":06789,"message":"test"}会被转换为{"xid":6789,"message":"test"},可正常解析为long类型 - 字符串格式带前导零
{"xid":"06789","message":"test"}会被转换为{"xid":6789,"message":"test"},正常绑定 - 普通数字
{"xid":12345,"message":"test"}和字符串数字{"xid":"12345","message":"test"}均不受影响 - 全零场景
{"xid":"0000","message":"test"}会被转换为{"xid":0,"message":"test"}
注意事项
- 若xid字段存在嵌套对象中,需调整正则表达式以支持深层匹配
- 处理大体积请求时,可改用流式处理逻辑,避免一次性读取整个请求体占用过多内存
- 需覆盖所有边缘测试场景:单数字带前导零、全零、超长数字等
内容的提问来源于stack exchange,提问作者Nat Webb
相关产品推荐
相关产品推荐

