是否可以在不使用 FromQuery 的情况下在 Swagger UI 中为输入模型属性指定不同的名称?
Is it possible to give input model properties different names in the Swagger UI, without using FromQuery?
public class InputModel
{
public string Thing { get; set; }
public DateTime AnotherThing { get; set; }
}
public ThingController : ControllerBase
{
public Task DoTheThing([FromQuery] int foo, [FromQuery] InputModel input)
{
// Elided.
}
}
问题是,当为此控制器生成 Swagger 文档时,会为 DoTheThing
列出以下输入:
foo: int
Thing: string
AnotherThing: DateTime
请注意最后两个输入是如何以大写字母开头的,因为这是它们在模型中的定义方式。 我希望它们以小写字母开头,以便与传递给控制器方法的非复杂参数保持一致(请记住,ASP.NET 模型绑定不关心大小写)。
执行此操作的简单方法是在模型上以小写字母开头命名这些属性,或者在它们上应用 FromQuery
and/or FromBody
属性。我不想做这两件事,因为前者很讨厌,而后者正在将行为应用于属性,当我需要根据具体情况应用该行为时。
理想情况下,我希望能够编写如下内容(目前不起作用,因为 Swashbuckle 似乎没有 know/care 关于 DisplayName
或 Display
属性):
public class InputModel
{
[DisplayName("thing")]
public string Thing { get; set; }
[DisplayName("anotherThing")]
public DateTime AnotherThing { get; set; }
}
但是,如果任何解决方案允许我 "rename" 模型属性而不更改它们的名称,我会很高兴。
我看过 Swashbuckle.AspNetCore.Annotations,但它似乎没有提供此功能。
您可以使用 Asp.Net 核心中的 IDocumentFilter
来实现,我不确定这是否会在正常 Asp.Net 中工作,但解决方案必须相似。
DocumentFilter 迭代所有参数并降低第一个字母。
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
/// <summary>
/// A DocumentFilter that lowers the first letter of the query parameters.
/// </summary>
public class NameDocumentFilter : IDocumentFilter
{
#region explicit interfaces
/// <inheritdoc />
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
if (swaggerDoc.Paths.Count <= 0)
{
return;
}
foreach (var path in swaggerDoc.Paths.Values)
{
ToLower(path.Parameters);
// Edit this list if you want other operations.
var operations = new List<Operation>
{
path.Get,
path.Post,
path.Put
};
operations.FindAll(x => x != null)
.ForEach(x => ToLower(x.Parameters));
}
}
#endregion
#region methods
/// <summary>
/// Lowers the first letter of a parameter name.
/// </summary>
private static void ToLower(IList<IParameter> parameters)
{
if (parameters == null)
{
return;
}
foreach (var param in parameters)
{
// limit the renaming only to query parameters
if (!param.In.Equals("query", StringComparison.OrdinalIgnoreCase))
{
continue;
}
// shouldn't happen, just to make sure
if (string.IsNullOrWhiteSpace(param.Name))
{
continue;
}
param.Name = param.Name[0]
.ToString()
.ToLower() + param.Name.Substring(1);
}
}
#endregion
}
然后在swagger配置中注册die DocumentFilter:
services.AddSwaggerGen(
c =>
{
c.SwaggerDoc(
"v1",
new Info
{
Title = "My WebSite",
Version = "v1"
});
c.DocumentFilter<NameDocumentFilter>();
});
我根据描述枚举参数的示例调整了这段代码,但同样的想法也适用于重命名。
要强制所有参数都为小写,请使用名称明显但文档不足的 DescribeAllParametersInCamelCase
方法:
services.AddSwaggerGen(o =>
{
...
o.DescribeAllParametersInCamelCase();
...
});
(这最终成为一个 XY 问题,因为我想要的是一种强制所有参数都被描述为小写的方法,但找不到方法来做到这一点,所以我要求一个通用的修改参数名称的方法。)
public class InputModel
{
public string Thing { get; set; }
public DateTime AnotherThing { get; set; }
}
public ThingController : ControllerBase
{
public Task DoTheThing([FromQuery] int foo, [FromQuery] InputModel input)
{
// Elided.
}
}
问题是,当为此控制器生成 Swagger 文档时,会为 DoTheThing
列出以下输入:
foo: int
Thing: string
AnotherThing: DateTime
请注意最后两个输入是如何以大写字母开头的,因为这是它们在模型中的定义方式。 我希望它们以小写字母开头,以便与传递给控制器方法的非复杂参数保持一致(请记住,ASP.NET 模型绑定不关心大小写)。
执行此操作的简单方法是在模型上以小写字母开头命名这些属性,或者在它们上应用 FromQuery
and/or FromBody
属性。我不想做这两件事,因为前者很讨厌,而后者正在将行为应用于属性,当我需要根据具体情况应用该行为时。
理想情况下,我希望能够编写如下内容(目前不起作用,因为 Swashbuckle 似乎没有 know/care 关于 DisplayName
或 Display
属性):
public class InputModel
{
[DisplayName("thing")]
public string Thing { get; set; }
[DisplayName("anotherThing")]
public DateTime AnotherThing { get; set; }
}
但是,如果任何解决方案允许我 "rename" 模型属性而不更改它们的名称,我会很高兴。
我看过 Swashbuckle.AspNetCore.Annotations,但它似乎没有提供此功能。
您可以使用 Asp.Net 核心中的 IDocumentFilter
来实现,我不确定这是否会在正常 Asp.Net 中工作,但解决方案必须相似。
DocumentFilter 迭代所有参数并降低第一个字母。
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
/// <summary>
/// A DocumentFilter that lowers the first letter of the query parameters.
/// </summary>
public class NameDocumentFilter : IDocumentFilter
{
#region explicit interfaces
/// <inheritdoc />
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
if (swaggerDoc.Paths.Count <= 0)
{
return;
}
foreach (var path in swaggerDoc.Paths.Values)
{
ToLower(path.Parameters);
// Edit this list if you want other operations.
var operations = new List<Operation>
{
path.Get,
path.Post,
path.Put
};
operations.FindAll(x => x != null)
.ForEach(x => ToLower(x.Parameters));
}
}
#endregion
#region methods
/// <summary>
/// Lowers the first letter of a parameter name.
/// </summary>
private static void ToLower(IList<IParameter> parameters)
{
if (parameters == null)
{
return;
}
foreach (var param in parameters)
{
// limit the renaming only to query parameters
if (!param.In.Equals("query", StringComparison.OrdinalIgnoreCase))
{
continue;
}
// shouldn't happen, just to make sure
if (string.IsNullOrWhiteSpace(param.Name))
{
continue;
}
param.Name = param.Name[0]
.ToString()
.ToLower() + param.Name.Substring(1);
}
}
#endregion
}
然后在swagger配置中注册die DocumentFilter:
services.AddSwaggerGen(
c =>
{
c.SwaggerDoc(
"v1",
new Info
{
Title = "My WebSite",
Version = "v1"
});
c.DocumentFilter<NameDocumentFilter>();
});
我根据描述枚举参数的示例调整了这段代码,但同样的想法也适用于重命名。
要强制所有参数都为小写,请使用名称明显但文档不足的 DescribeAllParametersInCamelCase
方法:
services.AddSwaggerGen(o =>
{
...
o.DescribeAllParametersInCamelCase();
...
});
(这最终成为一个 XY 问题,因为我想要的是一种强制所有参数都被描述为小写的方法,但找不到方法来做到这一点,所以我要求一个通用的修改参数名称的方法。)