[英]Does Swashbuckle support a way to represent custom operation tags as badges in the UI?
由於似乎沒有內置的方法來做到這一點,我設法通過一種非常hacky(但有效)的方法來實現這個結果,即使用操作過濾器將 append 文本以特定格式添加到操作摘要中,然后注入自定義 CS/JSS 將摘要描述的這些部分轉換為 DOM 中的自定義元素。
首先我定義一個自定義屬性:
/// <summary>
/// Indicates that this operation is intended for use solely by the development team.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class DeveloperToolAttribute : Attribute
{
}
然后我創建一個操作過濾器來處理這些:
public class DeveloperToolOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (!context.ApiDescription.CustomAttributes().Any(x => x is DeveloperToolAttribute))
return;
operation.Summary = $"[Developer Tool] {operation.Summary}";
}
}
我在其他根據 XML 文檔設置操作摘要的過濾器之后注冊此過濾器:
services.AddSwaggerGen(options =>
{
// ...
void AddXmlDocumentation(Assembly assembly)
{
var xmlFile = $"{assembly.GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath, includeControllerXmlComments: true);
}
// Set the comments path for the Swagger JSON and UI.
AddXmlDocumentation(Assembly.GetExecutingAssembly());
AddXmlDocumentation(typeof(StatementReadModel).Assembly);
// ...
options.OperationFilter<DeveloperToolOperationFilter>();
});
這樣我就可以使用[DeveloperTool]
注釋我的 API 方法,並將其作為操作摘要的一部分:
[HttpGet]
[DeveloperTool]
public async Task<CommissionAuthorisationsReadModel> GetAuthorisations()
{
var result = await _mediator.Send(CommissionAuthorisationsQuery.Instance);
return result;
}
接下來,我使用 TamperMonkey 構建了一個用戶腳本,它允許我遍歷包含這些操作摘要的所有 DOM 元素,並將大括號中的任何文本(例如[Developer Tool]
)轉換為徽章。
這使我能夠生成以下 Javascript 文件,我將其保存為wwwroot/ext/custom-swagger-javascript.js
:
var callback = function() {
var elements = document.getElementsByClassName("opblock-summary-description");
for (const summaryDescription of elements) {
const match = summaryDescription.textContent.match(/\[(\w|\s)+\]\s/);
if (!match) {
continue;
}
const trimmedTextContent = summaryDescription.textContent.replaceAll(match[0], "");
summaryDescription.textContent = trimmedTextContent;
const customTag = match[0].substring(1, match[0].length - 2);
const summary = summaryDescription.parentElement;
const customTagElement = document.createElement("div");
customTagElement.innerText = customTag;
customTagElement.className = "opblock-custom-tag";
summary.appendChild(customTagElement);
}
};
// Repeat just in case page is slow to load.
for (let attempts = 1; attempts <= 5; attempts++) {
setTimeout(callback, attempts * 200);
}
除此之外,我創建了一個 CSS 樣式表,保存為wwwroot/ext/custom-swagger-stylesheet.css
8CBA22E28EB17B5F5C6AE2A266AZ :
.opblock-custom-tag {
font-size: 10px;
font-weight: 700;
min-width: 80px;
padding: 6px 15px;
text-align: center;
border-radius: 3px;
background: #9d45d4;
text-shadow: 0 1px 0 rgba(0,0,0,.1);
font-family: sans-serif;
color: #fff;
}
在啟動中,我確保將注入這些 Javascript 和 CSS 文件:
app.UseSwaggerUI(c =>
{
// ...
c.InjectStylesheet("/ext/custom-swagger-stylesheet.css");
c.InjectJavascript("/ext/custom-swagger-javascript.js");
});
這還要求我確保 ASP.NET 內核可以為 static 文件提供服務:
app.UseHttpsRedirection();
app.UseStaticFiles(); // Added this
app.UseRouting();
最后,這一切都讓我得到了我想要的結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.