猿问

Net Core API:将 ProducesResponseType 设置为全局参数或自动化

我们有 100 多个 API,并且必须为我们所有的 API 在顶部、200 个、500 个等编写 ProducesResponseType。有没有一种方法可以为我们所有的 get 函数制作这个全局参数,这样我们就不必继续重复代码?尝试让API遵循Dry原则,成为瘦控制器。


[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);

}


慕运维8079593
浏览 261回答 2
2回答

小唯快跑啊

您可以创建自定义IApplicationModelProvider并在OnProvidersExecuting方法中添加所需的过滤器。ProduceResponseTypeModelProvider.cspublic class ProduceResponseTypeModelProvider : IApplicationModelProvider{&nbsp; &nbsp; public int Order => 3;&nbsp; &nbsp; public void OnProvidersExecuted(ApplicationModelProviderContext context)&nbsp; &nbsp; {&nbsp; &nbsp; }&nbsp; &nbsp; public void OnProvidersExecuting(ApplicationModelProviderContext context)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; foreach (ControllerModel controller in context.Result.Controllers)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (ActionModel action in controller.Actions)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // I assume that all you actions type are Task<ActionResult<ReturnType>>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Type returnType = action.ActionMethod.ReturnType.GenericTypeArguments[0].GetGenericArguments()[0];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status510NotExtended));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status200OK));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status500InternalServerError));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}然后你需要将其注册到IServiceCollection启动.cspublic void ConfigureServices(IServiceCollection services){&nbsp; &nbsp; ...&nbsp; &nbsp;&nbsp; &nbsp; services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ProduceResponseTypeModelProvider>());&nbsp; &nbsp; ...}

慕莱坞森

我们也使用这行代码, 它提供错误处理、动词属性检查以及参数是否存在,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);            }        }    }
随时随地看视频慕课网APP
我要回答