Swashbuckle/NSwag:关于swagger页面中接口地址不方便复制问题的一个解决办法
??之前有博友提到swagger页面的地址不好复制,我也有这种感觉,最近又有朋友跟我抱怨这个,所以今天花了点时间来看看有什么解决办法。
??原先,在一个swagger页面,如果想复制,当鼠标放在一个接口项上点击后,是无法进行选择的,因为点击表示打开这个选项卡!
??但是我们可以点击其它空白区域,然后进行选择是可以的:
??但是复制后,你会发现,前面的请求方法也会被复制,如果从后面拖选,那么注释就会被选中。。。
??通过F12发现,这块地址其实是在一个span里面:
??所以就有了一个想法,又能方便复制,又不影响现有功能,一个很好的办法就是让它变成可编辑,而我们的html元素就有个contenteditable属性,表示是否可编辑。
??我本来想看看有没有事件委托之类的,可以在让我们通过回调手动的添加这个属性,但是结果很遗憾。
??不过,通过查看index.html页面的源码,以及通过断点调试发现,swaggerUI其实是通过React来渲染的,正巧swagger将React相关函数等整合到一个ui对象中,然后将它挂到了window下:
??在控制台输出这个ui对象,发现里面的React对象有一个createElement函数,于是一个邪恶的想法来了:覆盖这个createElement函数,注入将页面所有的span设置成contenteditable!
??于是便有了这么一段代码:??
window.addEventListener('load', function () {
setTimeout(() => {
let createElement = window.ui.React.createElement
window.ui.React.createElement = function () {
let array = Array.from(arguments)
if (array.length == 3) {
if (array[0] == 'span' && !array[1]) {
array[1] = { contentEditable: true }
}
}
let ele = createElement(...array)
return ele
}
})
})
??接下来就是把这段代码注入了,巧的是Swashbuckle/NSwag都支持注入js代码,于是便有了下面两个拓展方法:
??如果是Swashbuckle:??
///
/// 设置Span为可编辑
///
///
public static void SetSpanEditable(this Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIOptions swaggerUIOptions)
{
StringBuilder stringBuilder = new StringBuilder(swaggerUIOptions.HeadContent);
stringBuilder.Append(@"
");
swaggerUIOptions.HeadContent = stringBuilder.ToString();
}
??使用的时候:??
app.UseSwagger();
app.UseSwaggerUI(options =>
{
//其它代码
options.SetSpanEditable();
});
??如果是NSwag:??
///
/// 设置Span为可编辑
///
///
public static void SetSpanEditable(this NSwag.AspNetCore.SwaggerUi3Settings swaggerUIOptions)
{
StringBuilder stringBuilder = new StringBuilder(swaggerUIOptions.CustomHeadContent);
stringBuilder.Append(@"
");
swaggerUIOptions.CustomHeadContent = stringBuilder.ToString();
}
??使用的时候:????
app.UseOpenApi();
app.UseSwaggerUi3(options =>
{
//其它代码
options.SetSpanEditable();
});
??运行后,点击接口地址,然后ctrl+A全选,ctrl+C完成复制了:
??注:虽然这个方法可以方便复制接口,但是因为可编辑,可能会导致某些意想不到的问题