我们有100+ APIs,并且必须为顶部的所有APIS编写ProducesResponseType,200,500等等。是否有方法为所有get函数创建这个全局参数,所以我们不需要继续重复代码?试图使API遵循干燥原理,成为瘦控制器。
[HttpGet("[Action]/{id}")]
[ProducesResponseType(typeof(GetBookResponse), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(GetBookResponse), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<GetBookResponse>> GetByBook(int id)
{
var book = await bookservice.GetBookById(id);
return Ok(book);
}
资源:
Set one ProducesResponseType typeof for several HttpStatusCodes
发布于 2019-09-22 08:53:36
您可以创建自定义IApplicationModelProvider
,并在OnProvidersExecuting
方法中添加所需的筛选器。
ProduceResponseTypeModelProvider.cs
public class ProduceResponseTypeModelProvider : IApplicationModelProvider
{
public int Order => 3;
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
foreach (ControllerModel controller in context.Result.Controllers)
{
foreach (ActionModel action in controller.Actions)
{
// I assume that all you actions type are Task<ActionResult<ReturnType>>
Type returnType = action.ActionMethod.ReturnType.GenericTypeArguments[0].GetGenericArguments()[0];
action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status510NotExtended));
action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status200OK));
action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status500InternalServerError));
}
}
}
}
然后您需要将它注册到IServiceCollection
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ProduceResponseTypeModelProvider>());
...
}
发布于 2019-12-28 21:53:59
Kahbazi答案是正确的,我们还使用了这一行代码,它提供了错误处理、动词属性检查,如果参数存在,
public class ProduceResponseTypeModelProvider : IApplicationModelProvider
{
public int Order => 3;
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
foreach (ControllerModel controller in context.Result.Controllers)
{
foreach (ActionModel action in controller.Actions)
{
Type returnType = null;
if (action.ActionMethod.ReturnType.GenericTypeArguments.Any())
{
if (action.ActionMethod.ReturnType.GenericTypeArguments[0].GetGenericArguments().Any())
{
returnType = action.ActionMethod.ReturnType.GenericTypeArguments[0].GetGenericArguments()[0];
}
}
var methodVerbs = action.Attributes.OfType<HttpMethodAttribute>().SelectMany(x => x.HttpMethods).Distinct();
bool actionParametersExist = action.Parameters.Any();
AddUniversalStatusCodes(action, returnType);
if (actionParametersExist == true)
{
AddProducesResponseTypeAttribute(action, null, 404);
}
if (methodVerbs.Contains("POST"))
{
AddPostStatusCodes(action, returnType, actionParametersExist);
}
}
}
}
public void AddProducesResponseTypeAttribute(ActionModel action, Type returnType, int statusCodeResult)
{
if (returnType != null)
{
action.Filters.Add(new ProducesResponseTypeAttribute(returnType, statusCodeResult));
}
else if (returnType == null)
{
action.Filters.Add(new ProducesResponseTypeAttribute(statusCodeResult));
}
}
public void AddUniversalStatusCodes(ActionModel action, Type returnType)
{
AddProducesResponseTypeAttribute(action, returnType, 200);
AddProducesResponseTypeAttribute(action, null, 500);
}
public void AddPostStatusCodes(ActionModel action, Type returnType, bool actionParametersExist)
{
AddProducesResponseTypeAttribute(action, returnType, 201);
AddProducesResponseTypeAttribute(action, returnType, 400);
if (actionParametersExist == false)
{
AddProducesResponseTypeAttribute(action, null, 404);
}
}
}
https://stackoverflow.com/questions/58047020
复制相似问题