C# Net Core API:使ProducesResponseType成为全局参数或自动化

C# Net Core API:使ProducesResponseType成为全局参数或自动化,c#,.net,asp.net-core,inheritance,.net-core,C#,.net,Asp.net Core,Inheritance,.net Core,我们有100多个API,必须为顶部的所有API(200、500等)编写ProducesResponseType。是否有一种方法可以为所有get函数生成此全局参数,因此我们不必继续重复代码?试图使API遵循Dry原则并成为精简控制器 [HttpGet("[Action]/{id}")] [ProducesResponseType(typeof(GetBookResponse), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.

我们有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);
}
资源:

您可以创建自定义IApplicationModelProvider,并在OnProvidersExecuting方法中添加所需的筛选器

ProduceResponseTypeModelProvider.cs

您可以创建自定义IApplicationModelProvider,并在OnProvidersExecuting方法中添加所需的筛选器

ProduceResponseTypeModelProvider.cs


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

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

公共整数顺序=>3也有什么作用?没有看到它使用了它的代码,其他一切看起来都很好,都在文档中。Order属性适用于具有多个IApplicationModelProvider并且可以设置首先运行哪个IApplicationModelProvider的情况。3只是一个随机数!您好,有时当我为我的api项目运行此程序时,我会遇到此错误,我查看特定的api,它没有[0]索引,但是api控制器存在,不确定为什么属性没有显示,是否有其他选择?System.IndexOutOfRangeException:'索引超出了数组的边界。'我认为可以简化它,尝试查找GetBookResponse的类型,这里还有一个问题,公共int顺序=>3做什么?没有看到它使用了它的代码,其他一切看起来都很好,都在文档中。Order属性适用于具有多个IApplicationModelProvider并且可以设置首先运行哪个IApplicationModelProvider的情况。3只是一个随机数!您好,有时当我为我的api项目运行此程序时,我会遇到此错误,我查看特定的api,它没有[0]索引,但是api控制器存在,不确定为什么属性没有显示,是否有其他选择?System.IndexOutOfRangeException:“索引超出了数组的界限。”我认为可以简化它,尝试查找GetBookResponse的类型,在这里蚀刻问题
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);
            }
        }
    }