Swagger UI中POST提交表单字符串被当作数字问题修复
最近何兄在使用Swagger UI时发现一个问题:一个由数字组成的字符串类型的参数(33028205011320003380),以表单POST测试时,数字的后几位会变,参数变成了33028205011320005000。我的第一反应是js的数字精度问题,Swagger UI把字符串当数字处理了。经过排查,果然在swagger-ui-bundle.js文件中找到了问题所在。
try {
u = JSON.parse(a[i])
} catch {
u = a[i]
}
buildRequest方法中,在已经知道POST提交的是表单的情况下,仍然先尝试转换为JSON对象,如果失败才用原始值。字符串经过JSON.parse方法处理后返回的就是一个数字了,而js中数字的精度有限,就导致了这个问题。这个代码片段的源代码地址在:https://github.com/swagger-api/swagger-js/blob/master/src/execute/oas3/build-request.js#L69
看了一下swagger官方对这个代码仓库也没有怎么维护,好多issue都提了3、4年了都没有人回复。就不提issue或者Pull request了。直接在项目中修改打补丁就好了。
直接修改swagger-ui-bundle.js文件对应位置,不使用JSON.parse,直接用原始值:
u = a[i]
然后将修改好的swagger-ui-bundle.js文件放到项目的Patches目录。在csproj文件中增加嵌入文件资源:
<ItemGroup>
<EmbeddedResource Include="Patches/swagger-ui-bundle.js" />
</ItemGroup>
然后在app.UseSwagger之前拦截这个文件,返回修改后的文件:
var embeddedFileProvider = new Microsoft.Extensions.FileProviders.EmbeddedFileProvider(typeof(WebServiceManager).Assembly);
app.Use(async (context, next) =>
{
var req = context.Request;
if (req.Path == "/swagger/swagger-ui-bundle.js")
{
var rep = context.Response;
var fileInfo = embeddedFileProvider.GetFileInfo("Patches/swagger-ui-bundle.js");
await rep.SendFileAsync(fileInfo);
return;
}
await next();
});
app.UseSwagger();
至此,问题解决。