/// <summary> /// Check each member of the actualProperty's array to make sure it matches the resource type specified for the property. /// </summary> /// <param name="actualProperty"></param> /// <param name="schemas"></param> /// <param name="detectedErrors"></param> /// <param name="options"></param> private PropertyValidationOutcome ValidateArrayProperty(ParameterDefinition actualProperty, Dictionary <string, JsonSchema> schemas, List <ValidationError> detectedErrors, ValidationOptions options) { JArray actualArray = (JArray)JsonConvert.DeserializeObject(actualProperty.OriginalValue); JsonSchema memberSchema; if (string.IsNullOrEmpty(actualProperty.Type.CustomTypeName)) { return(this.ValidateSimpleArrayProperty(actualProperty, this.ExpectedProperties[actualProperty.Name], detectedErrors)); } else if (!schemas.TryGetValue(actualProperty.Type.CustomTypeName, out memberSchema)) { detectedErrors.Add(new ValidationError(ValidationErrorCode.ResourceTypeNotFound, null, "Failed to locate resource definition for: {0}", actualProperty.Type.CustomTypeName)); return(PropertyValidationOutcome.MissingResourceType); } bool hadErrors = false; for (int i = 0; i < actualArray.Count; i++) { JContainer member = actualArray[i] as JContainer; if (member != null) { List <ValidationError> memberErrors = new List <ValidationError>(); memberSchema.ValidateContainerObject(member, options, schemas, memberErrors); // TODO: Filter out non-unique errors hadErrors |= memberErrors.Count > 0; detectedErrors.AddUniqueErrors(memberErrors); } } return(hadErrors ? PropertyValidationOutcome.GenericError : PropertyValidationOutcome.Ok); }
private void ValidateCollectionObject(JContainer obj, CodeBlockAnnotation annotation, Dictionary <string, JsonSchema> otherSchemas, string collectionPropertyName, List <ValidationError> detectedErrors, ValidationOptions options) { // TODO: also validate additional properties on the collection, like nextDataLink var collection = obj[collectionPropertyName]; if (null == collection) { detectedErrors.Add(new ValidationError(ValidationErrorCode.MissingCollectionProperty, null, "Failed to locate collection property '{0}' in response.", collectionPropertyName)); } else { var collectionMembers = obj[collectionPropertyName]; if (!collectionMembers.Any()) { if (!annotation.IsEmpty) { detectedErrors.Add( new ValidationWarning( ValidationErrorCode.CollectionArrayEmpty, null, "Property contained an empty array that was not validated: {0}", collectionPropertyName)); } } else if (annotation.IsEmpty) { detectedErrors.Add( new ValidationWarning( ValidationErrorCode.CollectionArrayNotEmpty, null, "Property contained a non-empty array that was expected to be empty: {0}", collectionPropertyName)); } foreach (var jToken in collectionMembers) { var container = jToken as JContainer; if (null != container) { List <ValidationError> containerErrors = new List <ValidationError>(); var deeperOptions = new ValidationOptions(options) { AllowTruncatedResponses = annotation.TruncatedResult }; this.ValidateContainerObject( container, deeperOptions, otherSchemas, containerErrors); detectedErrors.AddUniqueErrors(containerErrors); } } } }
/// <summary> /// Check each member of the actualProperty's array to make sure it matches the resource type specified for the property. /// </summary> /// <param name="actualProperty"></param> /// <param name="schemas"></param> /// <param name="detectedErrors"></param> /// <param name="options"></param> private PropertyValidationOutcome ValidateArrayProperty(ParameterDefinition actualProperty, Dictionary <string, JsonSchema> schemas, List <ValidationError> detectedErrors, ValidationOptions options) { JArray actualArray = null; try { actualArray = (JArray)JsonConvert.DeserializeObject(actualProperty.OriginalValue); } catch (InvalidCastException) { throw new InvalidCastException($"Property {actualProperty.Name} expected to be an array, but failed to cast value to an array: {actualProperty.OriginalValue}"); } var expectedPropertyDefinition = this.ExpectedProperties[actualProperty.Name]; JsonSchema memberSchema = null; if (actualProperty.Type.CollectionResourceType == SimpleDataType.Object && expectedPropertyDefinition.Type.CustomTypeName != null) { // We have an ambigious array, but we know what it's supposed to be so let's use that schemas.TryGetValue(expectedPropertyDefinition.Type.CustomTypeName, out memberSchema); } if (memberSchema == null && string.IsNullOrEmpty(actualProperty.Type.CustomTypeName)) { return(this.ValidateSimpleArrayProperty(actualProperty, this.ExpectedProperties[actualProperty.Name], detectedErrors)); } else if (memberSchema == null && !schemas.TryGetValue(actualProperty.Type.CustomTypeName, out memberSchema)) { detectedErrors.Add(new ValidationError(ValidationErrorCode.ResourceTypeNotFound, null, "Failed to locate resource definition for: {0}", actualProperty.Type.CustomTypeName)); return(PropertyValidationOutcome.MissingResourceType); } bool hadErrors = false; for (int i = 0; i < actualArray.Count; i++) { JContainer member = actualArray[i] as JContainer; if (member != null) { List <ValidationError> memberErrors = new List <ValidationError>(); memberSchema.ValidateContainerObject(member, options, schemas, memberErrors); // TODO: Filter out non-unique errors hadErrors |= memberErrors.Count > 0; detectedErrors.AddUniqueErrors(memberErrors); } } return(hadErrors ? PropertyValidationOutcome.GenericError : PropertyValidationOutcome.Ok); }
private void ValidateCollectionObject(JContainer obj, CodeBlockAnnotation annotation, Dictionary<string, JsonSchema> otherSchemas, string collectionPropertyName, List<ValidationError> detectedErrors, ValidationOptions options) { // TODO: also validate additional properties on the collection, like nextDataLink var collection = obj[collectionPropertyName]; if (null == collection) { detectedErrors.Add(new ValidationError(ValidationErrorCode.MissingCollectionProperty, null, "Failed to locate collection property '{0}' in response.", collectionPropertyName)); } else { var collectionMembers = obj[collectionPropertyName]; if (!collectionMembers.Any()) { if (!annotation.IsEmpty) { detectedErrors.Add( new ValidationWarning( ValidationErrorCode.CollectionArrayEmpty, null, "Property contained an empty array that was not validated: {0}", collectionPropertyName)); } } else if (annotation.IsEmpty) { detectedErrors.Add( new ValidationWarning( ValidationErrorCode.CollectionArrayNotEmpty, null, "Property contained a non-empty array that was expected to be empty: {0}", collectionPropertyName)); } foreach (var jToken in collectionMembers) { var container = jToken as JContainer; if (null != container) { List<ValidationError> containerErrors = new List<ValidationError>(); var deeperOptions = new ValidationOptions(options) { AllowTruncatedResponses = annotation.TruncatedResult }; this.ValidateContainerObject( container, deeperOptions, otherSchemas, containerErrors); detectedErrors.AddUniqueErrors(containerErrors); } } } }
/// <summary> /// Check each member of the actualProperty's array to make sure it matches the resource type specified for the property. /// </summary> /// <param name="actualProperty"></param> /// <param name="schemas"></param> /// <param name="detectedErrors"></param> /// <param name="options"></param> private PropertyValidationOutcome ValidateArrayProperty(ParameterDefinition actualProperty, Dictionary<string, JsonSchema> schemas, List<ValidationError> detectedErrors, ValidationOptions options) { JArray actualArray = null; try { actualArray = (JArray)JsonConvert.DeserializeObject(actualProperty.OriginalValue); } catch (InvalidCastException ex) { throw new InvalidCastException($"Property {actualProperty.Name} expected to be an array, but failed to cast value to an array: {actualProperty.OriginalValue}"); } var expectedPropertyDefinition = this.ExpectedProperties[actualProperty.Name]; JsonSchema memberSchema = null; if (actualProperty.Type.CollectionResourceType == SimpleDataType.Object && expectedPropertyDefinition.Type.CustomTypeName != null) { // We have an ambigious array, but we know what it's supposed to be so let's use that schemas.TryGetValue(expectedPropertyDefinition.Type.CustomTypeName, out memberSchema); } if (memberSchema == null && string.IsNullOrEmpty(actualProperty.Type.CustomTypeName)) { return this.ValidateSimpleArrayProperty(actualProperty, this.ExpectedProperties[actualProperty.Name], detectedErrors); } else if (memberSchema == null && !schemas.TryGetValue(actualProperty.Type.CustomTypeName, out memberSchema)) { detectedErrors.Add(new ValidationError(ValidationErrorCode.ResourceTypeNotFound, null, "Failed to locate resource definition for: {0}", actualProperty.Type.CustomTypeName)); return PropertyValidationOutcome.MissingResourceType; } bool hadErrors = false; for(int i=0; i<actualArray.Count; i++) { JContainer member = actualArray[i] as JContainer; if (member != null) { List<ValidationError> memberErrors = new List<ValidationError>(); memberSchema.ValidateContainerObject(member, options, schemas, memberErrors); // TODO: Filter out non-unique errors hadErrors |= memberErrors.Count > 0; detectedErrors.AddUniqueErrors(memberErrors); } } return hadErrors ? PropertyValidationOutcome.GenericError : PropertyValidationOutcome.Ok; }