是否可以在 dontnetcore api 应用程序中向路径变量添加参数验证?

is it possible to add parameter validations to path variables in a dontnetcore api app?

给定方法:

/// <param name="containername">The container the file resides in.</param>
/// <param name="fileName">The name of the file to get.</param>
/// <returns>The file specified.</returns>
[HttpGet("{containername}/contentfiles/{fileName}", Name = "Get")]
[ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status503ServiceUnavailable)]
public ActionResult Get(string containername, string fileName)

我检查 containername 和 fileName 是否对我的目的有效,然后获取数据。

Swagger 自动给我 *required,但没有最小长度和最大长度,这是有道理的,因为它不知道在哪里可以找到这些。

我希望我能做类似的事情:

/// <param name="containername" minimum="3" maximum="63">The container the file resides in.</param>

但它只是删除了那些。如何将它们添加到我自动生成的 swagger 文档中(我正在使用 swashbuckle,以防万一)?

我使用 ASP.NET Core 3.1 Api 项目创建了一个示例项目。

首先让我们看一下控制器并注意 ApiController 属性并注意 FromRoute 属性:

    using Microsoft.AspNetCore.Mvc;
    using System.ComponentModel.DataAnnotations;

    namespace ValidationExampleApi.Controllers
    {
      [ApiController]
      [Route("[controller]")]
      public class ValidationController : ControllerBase
      {
        [HttpGet("{containername}/contentfiles/{fileName}")]
        public bool Get([FromRoute]RequestModel request)//it will return 400 bad request if validation fails
        {
          if(ModelState.IsValid)//please note in this case this line will never be hit.
          {
            return false;
          }
          else
          {
            return true;
          }
        }
      }

    }

现在让我们看看模型并注意带有一些验证规范的数据注释:

    using Microsoft.AspNetCore.Mvc;
    using System.ComponentModel.DataAnnotations;

    namespace ValidationExampleApi.Controllers
    { 
      public class RequestModel
      {
        [Required(AllowEmptyStrings = false)]
        [StringLength(5, MinimumLength = 2)]
        public string containername { get; set; }

        [Required(AllowEmptyStrings = false)]
        [StringLength(5, MinimumLength = 2)]
        public string fileName { get; set; }
      }
    }

现在让我们看看我的启动 class 并注意我添加了香草默认的 swashbuckle 配置:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace ValidationExampleApi
{
  public class Startup
  {
    public Startup(IConfiguration configuration)
    {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddControllers();
      services.AddSwaggerGen(c =>
      {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
      });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if(env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
      }

      // Enable middleware to serve generated Swagger as a JSON endpoint.
      app.UseSwagger();

      // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
      // specifying the Swagger JSON endpoint.
      app.UseSwaggerUI(c =>
      {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        c.RoutePrefix = string.Empty;
      });

      app.UseRouting();

      app.UseAuthorization();

      app.UseEndpoints(endpoints =>
      {
        endpoints.MapControllers();
      });
    }
  }
}

现在看看我的招摇,这表明我违反了 MaxLength:

最后的笔记:

您还可以将路由参数与查询参数结合使用。 您还可以在模型的 属性 级别应用 "FromRoute" 属性。 有很多方法可以做到这一点。这只是一个 "get you started" 示例。

自定义错误响应:

在这里您可以看到如何使用错误处理程序以及 InvalidModelStateFactory 和 ValidationProblemDetails:Handle Errors Custom

这是另一个关于如何使用 InvalidModelStateFactory 的例子: Another example on how to customize error