为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
慕运维8079593 2023-12-17 20:03:46
我们有 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);}
查看完整描述

2 回答

?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

您可以创建自定义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


启动.cs


public void ConfigureServices(IServiceCollection services)

{

    ...   

    services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ProduceResponseTypeModelProvider>());

    ...

}


查看完整回答
反对 回复 2023-12-17
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

我们也使用这行代码, 它提供错误处理、动词属性检查以及参数是否存在,


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

            }

        }

    }


查看完整回答
反对 回复 2023-12-17
  • 2 回答
  • 0 关注
  • 128 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信