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();

至此,问题解决。