【问题标题】:Swashbuckle generated Swagger has errorsSwashbuckle 生成的 Swagger 有错误
【发布时间】:2017-02-06 20:15:23
【问题描述】:

我正在针对http://editor.swagger.io/ 测试 Swashbuckle nuget 包生成的 swagger 元数据,并在元数据中包含以下部分:

     "/User":{
     "get":{
              <snip>
     }
     "post":{
        "tags":[
           "User"
        ],
        "summary":"Create a new user, adds them to a space and sets dashboard view.",
        "operationId":"User_Post",
        "consumes":[
           "application/json",
           "text/json"
        ],
        "produces":[

        ],
        "parameters":[ // This line is marked as an error.
           {
              "name":"user",
              "in":"body",
              "description":"New user's username and assigned space.",
              "required":true,
              "schema":{
                 "$ref":"#/definitions/F1.Birst.CreateUserRequest"
              }
           },
           {
              "name":"Authorization",
              "in":"header",
              "description":"access token",
              "required":true,
              "type":"string"
           }
        ],
        "responses":{
           "204":{
              "description":"No Content"
           }
        },
        "deprecated":false
     }
  },

报告的错误是:

Swagger Error
Not a valid parameter definition
Jump to line 330
Details
 Object
code:  "ONE_OF_MISSING"
 params: Array [0]
message:  "Not a valid parameter definition"
 path: Array [5]
schemaId:  "http://swagger.io/v2/schema.json#"
 inner: Array [2]
level: 900
type:  "Swagger Error"
description:  "Not a valid parameter definition"
lineNumber: 330

使用 NSwag 生成代码似乎仍然没有问题。这是 Swagger 的编辑器的问题,还是 Swasbuckle 的问题,为什么 NSwag 能够毫无问题地处理这个问题?

其他swagger代码生成器会不会有这个问题?

如果 Swagger Editor 或 Swashbuckle 没有问题,我将如何在我的代码中解决这个问题?当前定义如下:

    /// <summary>
    /// Create a new user, adds them to a space and sets dashboard view.
    /// </summary>
    /// <param name="user">New user's username and assigned space.</param>
    public void Post([FromBody] CreateUserRequest user)

我试过了

    /// <summary>
    /// Create a new user, adds them to a space and sets dashboard view.
    /// </summary>
    /// <param name="user">New user's username and assigned space.</param>
    public void Post([FromBody][ModelBinder] CreateUserRequest user)

但最终将变量放入查询字符串中。

编辑:

这里是 CreateUserRequest 的定义。验证器为正则表达式抛出错误(这是有效的 C# 正则表达式)。我假设这是由于使用 JS 正则表达式语法的验证器造成的?

这会是“无效参数定义”的根本原因吗?如果是这样,那么我想它只是另一个错误的重复。在正则表达式中显示一个正则表达式错误,并且在将类作为参数引用时显示另一个错误?

  "F1.Birst.CreateUserRequest":{
     "required":[
        "username",
        "space"
     ],
     "type":"object",
     "properties":{
        "username":{
           "pattern":"(?i:^f1(\\.(test|churchstaff|churchuser|internal))?\\.\\d+\\.\\d+$)",
           "type":"string"
        },
        "space":{
           "pattern":"(?i:^f1\\.[\\d\\w]+$)",
           "type":"string"
        }
     }
  },

类定义:

public class CreateUserRequest
{
    [Required]
    [RegularExpression(@"(?i:^f1(\.(test|churchstaff|churchuser|internal))?\.\d+\.\d+$)")]
    public string Username { get; set; }

    [Required]
    [RegularExpression(@"(?i:^f1\.[\d\w]+$)")]
    public string Space { get; set; }
}

【问题讨论】:

  • 能否添加CreateUserRequest 类和F1.Birst.CreateUserRequest 定义?我想这有什么问题,因为当我将你的招摇撞到编辑器中时,它会完美验证(在添加一些必填字段并添加一个空对象定义之后)。
  • @venerik 我已经为你添加了定义。如果这都是由于正则表达式,我将如何解决期望 JS 正则表达式的验证器,但 .NET 期望 C# 正则表达式?
  • 为什么要将正则表达式放在一个命名组中?没有它,Swagger 的评估结果很好。
  • 您的正则表达式以 (?i: 开头并以匹配的 ) 结尾。那是一个命名组对吗?那有什么用?你不能没有那个吗?
  • 好的,祝你好运。可惜我帮不了你。

标签: c# asp.net rest swagger swashbuckle


【解决方案1】:

我能够通过创建一个接受选项参数的 RegularExpressionAttribute 版本并从正则表达式中删除不区分大小写的命名组来解决此问题。

属性定义

/// <summary>
/// Regular expression validation attribute with ability to specify options.
/// </summary>
/// <remarks>Swagger schema validation fails if you use the (?i:) named group for case insensitive regexes.</remarks>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class RegularExpressionWithOptionsAttribute : RegularExpressionAttribute
{
    private Regex Regex { get; set; }
    private RegexOptions Options { get; }

    /// <summary>
    /// Constructor that accepts the regular expression pattern
    /// </summary>
    /// <param name="pattern">The regular expression to use.  It cannot be null.</param>
    /// <param name="options">The options to use for the regular expression.</param>
    public RegularExpressionWithOptionsAttribute(string pattern, RegexOptions options)
        : base(pattern)
    {
        Options = options;
    }

    /// <summary>
    /// Override of <see cref="ValidationAttribute.IsValid(object)"/>
    /// </summary>
    /// <remarks>This override performs the specific regular expression matching of the given <paramref name="value"/></remarks>
    /// <param name="value">The value to test for validity.</param>
    /// <returns><c>true</c> if the given value matches the current regular expression pattern</returns>
    /// <exception cref="InvalidOperationException"> is thrown if the current attribute is ill-formed.</exception>
    /// <exception cref="ArgumentException"> is thrown if the <see cref="Pattern"/> is not a valid regular expression.</exception>
    public override bool IsValid(object value)
    {
        SetupRegex();

        // Convert the value to a string
        var stringValue = Convert.ToString(value, CultureInfo.CurrentCulture);

        // Automatically pass if value is null or empty. RequiredAttribute should be used to assert a value is not empty.
        if (string.IsNullOrEmpty(stringValue))
        {
            return true;
        }

        var match = Regex.Match(stringValue);

        // We are looking for an exact match, not just a search hit. This matches what
        // the RegularExpressionValidator control does
        return (match.Success && match.Index == 0 && match.Length == stringValue.Length);
    }

    /// <summary>
    /// Sets up the <see cref="Regex"/> property from the <see cref="Pattern"/> property.
    /// </summary>
    /// <exception cref="ArgumentException"> is thrown if the current <see cref="Pattern"/> cannot be parsed</exception>
    /// <exception cref="InvalidOperationException"> is thrown if the current attribute is ill-formed.</exception>
    /// <exception cref="ArgumentOutOfRangeException"> thrown if <see cref="MatchTimeoutInMilliseconds" /> is negative (except -1),
    /// zero or greater than approximately 24 days </exception>
    private void SetupRegex()
    {
        if (Regex != null)
            return;

        // Ensure base.SetupRegex is called, to check for empty pattern and setup timeout.
        base.IsValid(null);

        Regex = MatchTimeoutInMilliseconds == -1
            ? new Regex(Pattern, Options)
            : Regex = new Regex(Pattern, Options, TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds));
    }
}

用法

public class CreateUserRequest
{
    [Required]
    [RegularExpressionWithOptions(@"^f1(\.(test|churchstaff|churchuser|internal))?\.\d+\.\d+$", RegexOptions.IgnoreCase)]
    public string Username { get; set; }
    [Required]
    //[RegularExpressionWithOptions(@"^f1\.[\d\w]+$", RegexOptions.IgnoreCase)]
    public string Space { get; set; }
}

【讨论】:

    猜你喜欢
    • 2021-04-13
    • 2020-10-30
    • 2016-07-11
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    相关资源
    最近更新 更多