c# - .net Core - 添加过滤器时忽略响应类型
问题描述
在startup.cs
我为所有错误响应添加过滤器时,我通过抛出异常返回自己的错误对象(ErrorResponse),在中间件中我返回此代码作为响应。但是这些错误不是控制器方法中的返回类型,所以我必须为所有响应添加过滤器。它有效,在 swagger.json 中有这些响应,但没有响应类型(200),只有错误响应。
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ErrorResponse), (int)HttpStatusCode.BadRequest));
options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ErrorResponse), (int)HttpStatusCode.Unauthorized));
options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ErrorResponse), (int)HttpStatusCode.NotFound));
options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ErrorResponse), (int)HttpStatusCode.InternalServerError));
})
有人知道如何从控制器方法中保留默认返回类型吗?
谢谢你。:-)
解决方案
虽然我不完全确定为什么过滤器最终会删除由 给出的默认 200 响应类型ActionResult<T>
,但这是另一种可以完成的方法,尽管需要更多代码。此代码基于此答案:
public class ProduceResponseTypeModelProvider : IApplicationModelProvider
{
public int Order => 3;
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
var actions = context.Result.Controllers
.SelectMany(x => x.Actions);
foreach (var action in actions)
{
var returnType = action.ActionMethod.ReturnType;
// if the action returns Task<T>, use that T as the return type
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
{
returnType = returnType.GenericTypeArguments[0];
}
// if returnType is an ActionResult<T>, use that T for a 200 OK response
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(ActionResult<>))
{
var innerReturnType = returnType.GetGenericArguments()[0];
action.Filters.Add(new ProducesResponseTypeAttribute(innerReturnType, StatusCodes.Status200OK));
}
// otherwise, if the type is only IActionResult, return 204 No Content
else if (returnType == typeof(IActionResult))
{
action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status204NoContent));
}
// if there are input parameters, add 400 Bad Request as a possible result
if (action.Parameters.Count > 0)
{
action.Filters.Add(new ProducesResponseTypeAttribute(typeof(ProblemDetails), StatusCodes.Status400BadRequest));
}
// add common response types
action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status401Unauthorized));
action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status403Forbidden));
action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status404NotFound));
action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status500InternalServerError));
}
}
}
了解如何调整上述内容以返回ErrorResponse
特定响应应该相当简单。
上面可以注入:
services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ProduceResponseTypeModelProvider>());
推荐阅读
- java - 将用户输入读入数组列表?
- python - Dialogflow 天气 webhook 连接错误
- amazon-dynamodb - Dynamodb 扫描数组内的对象属性
- javascript - 如何比较两个 JSON 对象,不包括在单独数组中指定的字段?(邮递员脚本)
- javascript - 如何允许使用 cookie 注册多个帐户?提供的来源
- c# - 发出 Json 对象和 C#
- reinforcement-learning - 在强化学习中使用函数逼近时,如何选择动作?
- node.js - 如何使用 node.js 更改同一文件夹中的所有文件和文件夹权限
- firebase - Android Firebase-Analytics:无法将 null 设置为 userid 和 userproperty
- labview - 如何在 Labview 中对数字求和时增加常数?