首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Net核心API:使ProducesResponseType全局参数化或自动化

Net核心API:使ProducesResponseType全局参数化或自动化
EN

Stack Overflow用户
提问于 2019-09-22 07:28:59
回答 2查看 4.1K关注 0票数 2

我们有100+ APIs,并且必须为顶部的所有APIS编写ProducesResponseType,200,500等等。是否有方法为所有get函数创建这个全局参数,所以我们不需要继续重复代码?试图使API遵循干燥原理,成为瘦控制器。

代码语言:javascript
运行
复制
[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

Net Core API: Purpose of ProducesResponseType

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-22 08:53:36

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

ProduceResponseTypeModelProvider.cs

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
public void ConfigureServices(IServiceCollection services)
{
    ...   
    services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ProduceResponseTypeModelProvider>());
    ...
}
票数 10
EN

Stack Overflow用户

发布于 2019-12-28 21:53:59

Kahbazi答案是正确的,我们还使用了这一行代码,它提供了错误处理、动词属性检查,如果参数存在,

代码语言:javascript
运行
复制
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);
            }
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58047020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档