private static void AddValidationErrors(ModelStateEntry entry, string propertyName, Type resourceType, int operationIndex, List <ModelStateViolation> violations) { foreach (var error in entry.Errors) { var prefix = $"/atomic:operations[{operationIndex}]/data/attributes/"; var violation = new ModelStateViolation(prefix, propertyName, resourceType, error); violations.Add(violation); } }
protected virtual void ValidateModelState(IEnumerable <OperationContainer> operations) { // We must validate the resource inside each operation manually, because they are typed as IIdentifiable. // Instead of validating IIdentifiable we need to validate the resource runtime-type. var violations = new List <ModelStateViolation>(); int index = 0; foreach (var operation in operations) { if (operation.Kind == OperationKind.CreateResource || operation.Kind == OperationKind.UpdateResource) { _targetedFields.Attributes = operation.TargetedFields.Attributes; _targetedFields.Relationships = operation.TargetedFields.Relationships; _request.CopyFrom(operation.Request); var validationContext = new ActionContext(); ObjectValidator.Validate(validationContext, null, string.Empty, operation.Resource); if (!validationContext.ModelState.IsValid) { foreach (var(key, entry) in validationContext.ModelState) { foreach (var error in entry.Errors) { var violation = new ModelStateViolation($"/atomic:operations[{index}]/data/attributes/", key, operation.Resource.GetType(), error); violations.Add(violation); } } } } index++; } if (violations.Any()) { var namingStrategy = _options.SerializerContractResolver.NamingStrategy; throw new InvalidModelStateException(violations, _options.IncludeExceptionStackTraceInErrors, namingStrategy); } }