我正在测试Swashbuckle nuget包针对http://editor.swagger.io/生成的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正则表达式语法?
这是&#34;不是有效参数定义的基本原因&#34;?如果是这样,那么我认为它只是另一个错误的副本。在正则表达式中显示正则表达式错误,以及在将类作为参数引用时出现另一个错误?
"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; }
}
答案 0 :(得分:0)
我能够通过创建一个接受options参数的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; }
}