// add more rule. /// <summary> /// Checks if the schemas in the list contain a property with the property name specified by the discriminator. /// </summary> private static void ValidateSchemaListDiscriminator(IValidationContext context, string ruleName, IList <OpenApiSchema> schemas, OpenApiDiscriminator discriminator) { foreach (var schema in schemas) { if (schema.Reference != null && !schema.Properties.ContainsKey(discriminator.PropertyName)) { context.CreateError(ruleName, string.Format(SRResource.Validation_CompositeSchemaMustContainPropertySpecifiedInTheDiscriminator, schema.Reference.Id, discriminator.PropertyName)); } if (schema.Reference != null && !schema.Required.Contains(discriminator.PropertyName)) { context.CreateError(ruleName, string.Format(SRResource.Validation_CompositeSchemaRequiredFieldListMustContainThePropertySpecifiedInTheDiscriminator, schema.Reference.Id, discriminator.PropertyName)); } } }
private static void ValidateKeys(IValidationContext context, IEnumerable <string> keys, string component) { if (keys == null) { return; } foreach (var key in keys) { if (!KeyRegex.IsMatch(key)) { context.CreateError(nameof(KeyMustBeRegularExpression), string.Format(SRResource.Validation_ComponentsKeyMustMatchRegularExpr, key, component, KeyRegex.ToString())); } } }
/// <summary> /// Checks an <see cref="OpenApiSchema"/> for internal consistency. /// </summary> /// <param name="context">Validation context, enabling errors to be reported.</param> /// <param name="schema">The schema to check.</param> public static void ValidateSchema( IValidationContext context, OpenApiSchema schema) { if (schema.Type == "object") { if (!schema.AdditionalPropertiesAllowed) { IEnumerable <string> allProperties = EnumerableEx .Return(schema) .Expand(s => s.AdditionalProperties == null ? Enumerable.Empty <OpenApiSchema>() : EnumerableEx.Return(s.AdditionalProperties)) .SelectMany(s => s.Properties.Keys); foreach (string propertyName in schema.Required.Except(allProperties)) { context.CreateError( "InvalidRequiredProperty", $"Required properties include '{propertyName}', which is not recognized."); } } } }
public static void ValidateDataTypeMismatch( IValidationContext context, string ruleName, IOpenApiAny value, OpenApiSchema schema) { if (schema == null) { return; } var type = schema.Type; var format = schema.Format; if (type == "object") { // It is not against the spec to have a string representing an object value. // To represent examples of media types that cannot naturally be represented in JSON or YAML, // a string value can contain the example with escaping where necessary if (value is OpenApiString) { return; } // If value is not a string and also not an object, there is a data mismatch. if (!(value is OpenApiObject)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); return; } var anyObject = (OpenApiObject)value; foreach (var key in anyObject.Keys) { context.Enter(key); if (schema.Properties != null && schema.Properties.ContainsKey(key)) { ValidateDataTypeMismatch(context, ruleName, anyObject[key], schema.Properties[key]); } else { ValidateDataTypeMismatch(context, ruleName, anyObject[key], schema.AdditionalProperties); } context.Exit(); } return; } if (type == "array") { // It is not against the spec to have a string representing an array value. // To represent examples of media types that cannot naturally be represented in JSON or YAML, // a string value can contain the example with escaping where necessary if (value is OpenApiString) { return; } // If value is not a string and also not an array, there is a data mismatch. if (!(value is OpenApiArray)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); return; } var anyArray = (OpenApiArray)value; for (int i = 0; i < anyArray.Count; i++) { context.Enter(i.ToString()); ValidateDataTypeMismatch(context, ruleName, anyArray[i], schema.Items); context.Exit(); } return; } if (type == "integer" && format == "int32") { if (!(value is OpenApiInteger)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "integer" && format == "int64") { if (!(value is OpenApiLong)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "integer" && !(value is OpenApiInteger)) { if (!(value is OpenApiInteger)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "number" && format == "float") { if (!(value is OpenApiFloat)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "number" && format == "double") { if (!(value is OpenApiDouble)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "number") { if (!(value is OpenApiDouble)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "string" && format == "byte") { if (!(value is OpenApiByte)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "string" && format == "date") { if (!(value is OpenApiDate)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "string" && format == "date-time") { if (!(value is OpenApiDateTime)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "string" && format == "password") { if (!(value is OpenApiPassword)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "string") { if (!(value is OpenApiString)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } if (type == "boolean") { if (!(value is OpenApiBoolean)) { context.CreateError( ruleName, DataTypeMismatchedErrorMessage); } return; } }