Example #1
0
        ConstraintsViolationException ValidateNumber(double v, State state, JsonSchemaRegistory reg)
        {
            if (_schema.MultipleOf != double.MinValue)
            {
                if (_schema.MultipleOf <= 0)
                {
                    throw new InvalidOperationException("MultipleOf must be greater than 0: Value = " + _schema.MultipleOf);
                }

                var b = v / _schema.MultipleOf;
                if (b != Math.Truncate(b))
                {
                    var msg = state.CreateMessage("MultipleOf assertion !({0} % {1} == 0)",
                                                  v, _schema.MultipleOf);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.Maximum != double.MinValue)
            {
                if (!(v <= _schema.Maximum))
                {
                    var msg = state.CreateMessage("Maximum assertion !({0} <= {1})",
                                                  v, _schema.Maximum);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.ExclusiveMaximum != double.MinValue)
            {
                if (!(v < _schema.ExclusiveMaximum))
                {
                    var msg = state.CreateMessage("ExclusiveMaximum assertion !({0} < {1})",
                                                  v, _schema.ExclusiveMaximum);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.Minimum != double.MaxValue)
            {
                if (!(v >= _schema.Minimum))
                {
                    var msg = state.CreateMessage("Minimum assertion !({0} >= {1})",
                                                  v, _schema.Minimum);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.ExclusiveMinimum != double.MaxValue)
            {
                if (!(v > _schema.ExclusiveMinimum))
                {
                    var msg = state.CreateMessage("ExclusiveMinimum assertion !({0} > {1})",
                                                  v, _schema.ExclusiveMinimum);
                    return(new ConstraintsViolationException(msg));
                }
            }

            return(null);
        }
Example #2
0
 internal static ConstraintsViolationException Validate(this JsonSchemaAttribute j,
                                                        object o,
                                                        Internal.State state,
                                                        JsonSchemaRegistory reg)
 {
     return((new JsonSchemaValidator(j)).Validate(o, state, reg));
 }
Example #3
0
        ConstraintsViolationException ValidateString(string v, State state, JsonSchemaRegistory reg)
        {
            StringInfo si = null;

            if (_schema.MaxLength != int.MinValue)
            {
                si = si ?? new StringInfo(v);
                if (!(si.LengthInTextElements <= _schema.MaxLength))
                {
                    var msg = state.CreateMessage("MaxLength assertion !({0} <= {1})",
                                                  si.LengthInTextElements, _schema.MaxLength);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.MinLength != int.MaxValue)
            {
                si = si ?? new StringInfo(v);
                if (!(si.LengthInTextElements >= _schema.MinLength))
                {
                    var msg = state.CreateMessage("MinLength assertion !({0} >= {1})",
                                                  si.LengthInTextElements, _schema.MinLength);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.Pattern != null)
            {
                if (!Regex.IsMatch(v, _schema.Pattern))
                {
                    var msg = state.CreateMessage("Pattern assertion !(\"{0}\" matched \"{1}\")",
                                                  v, _schema.Pattern);
                    return(new ConstraintsViolationException(msg));
                }
            }

            return(null);
        }
Example #4
0
        ConstraintsViolationException ValidateObjectField(string key,
                                                          object value,
                                                          State state,
                                                          JsonSchemaRegistory reg)
        {
            var matched = false;

            if (_schema._dynamicResolverTag != null)
            {
                Type dynElemType;
                if (DynamicResolver.Find(_schema._dynamicResolverTag, key, out dynElemType))
                {
                    var dynElemSchema = JsonSchemaAttribute.CreateFromType(dynElemType, reg, true);
                    var ex            = dynElemSchema.Validate(value, state, reg);

                    if (ex != null)
                    {
                        return(new ConstraintsViolationException("DynamicResolver", ex));
                    }
                }
            }

            if (_schema.Properties != null)
            {
                JsonSchemaAttribute itemSchema = null;
                if (_schema.Properties.TryGetValue(key, out itemSchema))
                {
                    matched = true;

                    var ex = itemSchema.Validate(value, state, reg);
                    if (ex != null)
                    {
                        return(new ConstraintsViolationException("Property", ex));
                    }
                }
            }

            if (_schema.PatternProperties != null)
            {
                foreach (var pprop in _schema.PatternProperties)
                {
                    if (Regex.IsMatch(key, pprop.Key))
                    {
                        matched = true;

                        var ex = pprop.Value.Validate(value, state, reg);
                        if (ex != null)
                        {
                            return(new ConstraintsViolationException("PatternProperties", ex));
                        }
                    }
                }
            }

            if (_schema.AdditionalProperties != null && !matched)
            {
                var ex = _schema.AdditionalProperties.Validate(value, state, reg);
                if (ex != null)
                {
                    return(new ConstraintsViolationException("AdditionalProperties", ex));
                }
            }

            return(null);
        }
Example #5
0
        ConstraintsViolationException ValidateObject(object v, State state, JsonSchemaRegistory reg)
        {
            var validated = new Dictionary <string, object>();

            foreach (var kv in TypeHelper.ToKeyValues(v))
            {
                var ex = ValidateObjectField(kv.Key, kv.Value, state.NestAsElem(kv.Key), reg);
                if (ex != null)
                {
                    return(ex);
                }

                validated.Add(kv.Key, kv.Value);
            }

            if (_schema.Required != null)
            {
                var req = new HashSet <string>(_schema.Required);
                req.IntersectWith(validated.Keys);

                if (req.Count != _schema.Required.Count())
                {
                    var actual   = String.Join(", ", req.ToArray());
                    var expected = String.Join(", ", _schema.Required);
                    var msg      = state.CreateMessage("Lack of required fields(Actual: [{0}]; Expected: [{1}])",
                                                       actual, expected);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.MaxProperties != int.MinValue)
            {
                if (!(validated.Count <= _schema.MaxProperties))
                {
                    var msg = state.CreateMessage("MaxProperties assertion !({0} <= {1})",
                                                  validated.Count, _schema.MaxProperties);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.MinProperties != int.MaxValue)
            {
                if (!(validated.Count >= _schema.MinProperties))
                {
                    var msg = state.CreateMessage("MaxProperties assertion !({0} >= {1})",
                                                  validated.Count, _schema.MinProperties);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.Dependencies != null)
            {
                var strDep = _schema.Dependencies as Dictionary <string, string[]>;
                if (strDep != null)
                {
                    foreach (var va in validated)
                    {
                        string[] deps = null;
                        if (strDep.TryGetValue(va.Key, out deps))
                        {
                            var intersected = ((string[])deps.Clone()).Intersect(validated.Keys);
                            if (intersected.Count() != deps.Count())
                            {
                                var actual   = String.Join(", ", intersected.ToArray());
                                var expected = String.Join(", ", deps);
                                var msg      = state.CreateMessage("Dependencies assertion. Lack of depended fields for {0}(Actual: [{1}]; Expected: [{2}])",
                                                                   va.Key, actual, expected);
                                return(new ConstraintsViolationException(msg));
                            }
                        }
                    }
                    goto depChecked;
                }

                var schemaDep = _schema.Dependencies as Dictionary <string, JsonSchemaAttribute>;
                if (schemaDep != null)
                {
                    foreach (var va in validated)
                    {
                        JsonSchemaAttribute ext = null;
                        if (schemaDep.TryGetValue(va.Key, out ext))
                        {
                            var ex = ext.Validate(v, new State().NestAsElem(va.Key), reg);
                            if (ex != null)
                            {
                                // TODO:
                                var msg = state.CreateMessage("Dependencies assertion. Failed to validation for {0}",
                                                              va.Key);
                                return(new ConstraintsViolationException(msg, ex));
                            }
                        }
                    }
                }

depChecked:
                ;
            }

            return(null);
        }
Example #6
0
        ConstraintsViolationException ValidateArray(IEnumerable <object> v, State state, JsonSchemaRegistory reg)
        {
            var length = v.Count();

            if (_schema.MaxItems != int.MinValue)
            {
                if (!(length <= _schema.MaxItems))
                {
                    var msg = state.CreateMessage("MaxItems assertion !({0} <= {1})",
                                                  length, _schema.MaxItems);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.MinItems != int.MaxValue)
            {
                if (!(length >= _schema.MinItems))
                {
                    var msg = state.CreateMessage("MinItems assertion !({0} >= {1})",
                                                  length, _schema.MinItems);
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.UniqueItems)
            {
                // O(N^2) to use DeepEquals...
                var i = 0;
                foreach (var elem in v)
                {
                    var j = 0;
                    foreach (var elemS in v)
                    {
                        if (i == j)
                        {
                            continue;
                        }

                        if (TypeHelper.DeepEquals(elem, elemS))
                        {
                            var msg = state.CreateMessage("UniqueItems assertion: Elements at {0} and {1} are duplicated",
                                                          i, j);
                            return(new ConstraintsViolationException(msg));
                        }

                        ++j;
                    }

                    ++i;
                }
            }

            List <object> extraItems = null;

            if (_schema.Items != null)
            {
                if (_schema.Items.GetType().IsArray)
                {
                    var itemSchemas = (JsonSchemaAttribute[])_schema.Items;

                    var i = 0;
                    foreach (var elem in v)
                    {
                        var itemSchema = itemSchemas.ElementAtOrDefault(i);
                        if (itemSchema == null)
                        {
                            if (extraItems == null)
                            {
                                extraItems = new List <object>();
                            }
                            extraItems.Add(elem);
                            continue;
                        }

                        var ex = itemSchema.Validate(elem, state.NestAsElem(i), reg);
                        if (ex != null)
                        {
                            return(new ConstraintsViolationException("Items", ex));
                        }

                        ++i;
                    }
                }
                else
                {
                    var itemSchema = (JsonSchemaAttribute)_schema.Items;
                    var i          = 0;
                    foreach (var elem in v)
                    {
                        var ex = itemSchema.Validate(elem, state.NestAsElem(i), reg);
                        if (ex != null)
                        {
                            return(new ConstraintsViolationException("Items", ex));
                        }

                        ++i;
                    }
                }
            }

            if (_schema.AdditionalItems != null)
            {
                if (extraItems != null)
                {
                    foreach (var elem in extraItems)
                    {
                        var ex = _schema.AdditionalItems.Validate(elem, state, reg);
                        if (ex != null)
                        {
                            return(new ConstraintsViolationException("AdditionalItems", ex));
                        }
                    }
                }
            }

            return(null);
        }
Example #7
0
        internal ConstraintsViolationException Validate(object o, State state, JsonSchemaRegistory reg)
        {
            if (_schema.Ref != null)
            {
                if (reg == null)
                {
                    reg = JsonSchemaRegistory.GetDefault();
                }
                var schema = reg.Resolve(_schema.Ref);
                if (schema == null)
                {
                    // TODO:
                    throw new NotSupportedException();
                }
                return(schema.Validate(o, state, reg));
            }

            ConstraintsViolationException ex = null;

            var kind = Node.KindOfValue(o);

            if (_schema.Type != null)
            {
                if (_schema.Type.GetType().IsArray)
                {
                    var ts    = (string[])_schema.Type;
                    var found = false;
                    foreach (var t in ts)
                    {
                        if (ValidateKind(kind, t))
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        var actual   = kind.ToString();
                        var expected = String.Join(", ", ts);
                        var msg      = state.CreateMessage("Type is not contained(Actual: {0}; Expected: [{1}])",
                                                           actual, expected);
                        return(new ConstraintsViolationException(msg));
                    }
                }
                else
                {
                    var t = (string)_schema.Type;
                    if (!ValidateKind(kind, t))
                    {
                        var actual   = kind.ToString();
                        var expected = t.ToString();
                        var msg      = state.CreateMessage("Type is not matched(Actual: {0}; Expected: {1})",
                                                           actual, expected);
                        return(new ConstraintsViolationException(msg));
                    }
                }
            }

            if (_schema.Enum != null)
            {
                var oEnum = o;
                if (o != null && TypeHelper.TypeWrap(o.GetType()).IsEnum&& kind == NodeKind.String)
                {
                    oEnum = TypeHelper.GetStringEnumNameOf(o);
                }

                var found = false;
                foreach (var e in _schema.Enum)
                {
                    if (TypeHelper.DeepEquals(oEnum, e))
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    var msg = state.CreateMessage("Enum is not matched");
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.Not != null)
            {
                ex = _schema.Not.Validate(o, state, reg);
                if (ex == null)
                {
                    var msg = state.CreateMessage("Not");
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.AllOf != null)
            {
                var i = 0;
                foreach (var jsonSchema in _schema.AllOf)
                {
                    ex = jsonSchema.Validate(o, state, reg);
                    if (ex != null)
                    {
                        var msg = state.CreateMessage("AllOf[{0}] is failed", i);
                        return(new ConstraintsViolationException(msg, ex));
                    }

                    ++i;
                }
            }

            if (_schema.AnyOf != null)
            {
                var schemaChecked = false;
                foreach (var jsonSchema in _schema.AnyOf)
                {
                    ex = jsonSchema.Validate(o, state, reg);
                    if (ex == null)
                    {
                        schemaChecked = true;
                        break;
                    }
                }
                if (!schemaChecked)
                {
                    var msg = state.CreateMessage("None of AnyOf is matched");
                    return(new ConstraintsViolationException(msg));
                }
            }

            if (_schema.OneOf != null)
            {
                var checkedI = -1;
                var i        = 0;
                foreach (var jsonSchema in _schema.OneOf)
                {
                    ex = jsonSchema.Validate(o, state, reg);
                    if (ex == null)
                    {
                        if (checkedI != -1)
                        {
                            var msg = state.CreateMessage("Both of OneOf[{0}] and OneOf[{1}] are matched", checkedI, i);
                            return(new ConstraintsViolationException(msg));
                        }

                        checkedI = i;
                    }

                    ++i;
                }
                if (checkedI == -1)
                {
                    var msg = state.CreateMessage("None of AnyOf is matched");
                    return(new ConstraintsViolationException(msg));
                }
            }

            switch (kind)
            {
            case NodeKind.Boolean:
                break;

            case NodeKind.Float:
            case NodeKind.Integer:
                ex = ValidateNumber(Convert.ToDouble(o), state, reg);

                if (ex != null)
                {
                    return(new ConstraintsViolationException("Number", ex));
                }
                break;

            case NodeKind.String:
                var oConverted =
                    (o != null && TypeHelper.TypeWrap(o.GetType()).IsEnum)
                        ? TypeHelper.GetStringEnumNameOf(o)
                        : (string)o;

                ex = ValidateString(oConverted, state, reg);
                if (ex != null)
                {
                    return(new ConstraintsViolationException("String", ex));
                }
                break;

            case NodeKind.Array:
                ex = ValidateArray(TypeHelper.ToIEnumerable(o), state, reg);
                if (ex != null)
                {
                    return(new ConstraintsViolationException("Array", ex));
                }
                break;

            case NodeKind.Object:
                ex = ValidateObject(o, state, reg);
                if (ex != null)
                {
                    return(new ConstraintsViolationException("Object", ex));
                }
                break;

            case NodeKind.Null:
                break;

            default:
                throw new NotImplementedException(kind.ToString());
            }

            return(null);
        }
Example #8
0
 public ConstraintsViolationException Validate(object o, JsonSchemaRegistory reg = null)
 {
     return(Validate(o, new State(), reg));
 }
Example #9
0
 public static ConstraintsViolationException Validate(this JsonSchemaAttribute j,
                                                      object o,
                                                      JsonSchemaRegistory reg = null)
 {
     return((new JsonSchemaValidator(j)).Validate(o, reg));
 }
Example #10
0
        public static JsonSchemaAttribute CreateFromType(Type ty, JsonSchemaRegistory reg = null, bool asRef = false)
        {
            var kind = Node.KindOfType(ty);

            switch (kind)
            {
            case NodeKind.Boolean:
                return(new JsonSchemaAttribute
                {
                    Type = "boolean",
                });

            case NodeKind.Integer:
                object[] enumsForInteger = null;
                if (TypeHelper.TypeWrap(ty).IsEnum)
                {
                    enumsForInteger = System.Enum.GetValues(ty).Cast <object>().ToArray();
                }
                return(new JsonSchemaAttribute
                {
                    Type = "integer",
                    Enum = enumsForInteger,
                });

            case NodeKind.Float:
                return(new JsonSchemaAttribute
                {
                    Type = "number",
                });

            case NodeKind.String:
                object[] enumsForString = null;
                if (TypeHelper.TypeWrap(ty).IsEnum)
                {
                    enumsForString = TypeHelper.GetStringEnumNames(ty);
                }
                return(new JsonSchemaAttribute
                {
                    Type = "string",
                    Enum = enumsForString,
                });

            case NodeKind.Array:
                var elemTy = TypeHelper.ElemTypeOfIEnumerable(ty);
                return(new JsonSchemaAttribute
                {
                    Type = "array",
                    Items = elemTy != null?CreateFromType(elemTy, reg, true) : null,
                });

            case NodeKind.Object:
                if (ty == typeof(object))
                {
                    return(new JsonSchemaAttribute());
                }

                if (TypeHelper.TypeWrap(ty).IsGenericType&& ty.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    return(new JsonSchemaAttribute
                    {
                        Type = "object",
                    });
                }

                break;

            default:
                throw new NotImplementedException();
            }

            if (reg == null)
            {
                reg = JsonSchemaRegistory.GetDefault();
            }

            var schema = TypeHelper.GetCustomAttribute <JsonSchemaAttribute>(ty);

            if (schema == null)
            {
                schema = new JsonSchemaAttribute();
            }
            schema.Type = "object";

            var schemaId = schema.Id;

            if (schemaId == null)
            {
                schemaId = ty.ToString();
            }
            var refSchema = reg.Resolve(schemaId);

            if (refSchema != null)
            {
                schema = refSchema;
                goto skip;
            }
            else
            {
                reg.Register(schemaId, schema);
            }

            var baseType = TypeHelper.TypeWrap(ty).BaseType;
            HashSet <string> baseFieldNames = null;

            if (baseType != null)
            {
                Type schemaBaseType;
                if (RefChecker.IsRefTag(baseType, out schemaBaseType))
                {
                    var baseSchemaValue = CreateFromType(schemaBaseType, reg, false);
                    schema.Type = baseSchemaValue.Type;

                    goto skip;
                }

                // Nest fields included in the base class
                var baseSchema = CreateFromType(baseType, reg, true);
                if (baseSchema != null && baseSchema.Ref != null)
                {
                    schema.AddToAllOf(baseSchema);

                    var baseFields = TypeHelper.TypeWrap(baseType).GetFields(BindingFlags.Public | BindingFlags.Instance);
                    baseFieldNames = new HashSet <string>(baseFields.Select(f => f.Name));
                }
            }

            var properties   = new Dictionary <string, JsonSchemaAttribute>();
            var required     = new List <string>();
            var dependencies = new Dictionary <string, string[]>();

            var fields = TypeHelper.TypeWrap(ty).GetFields(BindingFlags.Public | BindingFlags.Instance);

            foreach (var field in fields)
            {
                var fieldType = field.FieldType;

                JsonSchemaAttribute fieldSchema = null;
                var attr     = TypeHelper.GetCustomAttribute <JsonFieldAttribute>(field);
                var elemName = JsonFieldAttribute.FieldName(attr, field); // TODO: duplication check

                // If elements are also included in Base classes, skip collecting a schema for the elements.
                if (baseFieldNames != null && baseFieldNames.Contains(field.Name))
                {
                    fieldSchema = new JsonSchemaAttribute();
                    goto skipField;
                }

                fieldSchema = TypeHelper.GetCustomAttribute <JsonSchemaAttribute>(field);
                if (fieldSchema == null)
                {
                    fieldSchema = new JsonSchemaAttribute();
                }

                var fieldItemsSchema = TypeHelper.GetCustomAttribute <ItemsJsonSchemaAttribute>(field);
                if (fieldItemsSchema != null)
                {
                    fieldSchema.Items = fieldItemsSchema;
                }

                if (attr != null && attr.DynamicResolverTag != null)
                {
                    if (!TypeHelper.TypeWrap(fieldType).IsGenericType || fieldType.GetGenericTypeDefinition() != typeof(Dictionary <,>))
                    {
                        var baseMsg = "A type of the field which has DynamicResolver must be a Dictionary<,>";
                        var msg     = string.Format("{0}: Type = {1} at \"{2}\" of {3}", baseMsg, fieldType, elemName, ty);
                        throw new ArgumentException(msg);
                    }

                    var keyType = TypeHelper.TypeWrap(fieldType).GetGenericArguments()[0];
                    if (keyType != typeof(string))
                    {
                        var baseMsg = "A key of the dictionary which has DynamicResolver must be a string type";
                        var msg     = string.Format("{0}: KeyType = {1} at \"{2}\" of {3}", baseMsg, keyType, elemName, ty);
                        throw new ArgumentException(msg);
                    }

                    fieldSchema._dynamicResolverTag = attr.DynamicResolverTag;
                }

                var fieldItemRequired = TypeHelper.GetCustomAttribute <JsonSchemaRequiredAttribute>(field);
                if (fieldItemRequired != null)
                {
                    required.Add(elemName);
                }

                var fieldItemDependencies = TypeHelper.GetCustomAttribute <JsonSchemaDependenciesAttribute>(field);
                if (fieldItemDependencies != null)
                {
                    dependencies.Add(elemName, fieldItemDependencies.Dependencies);
                }

                var fieldTypeSchema = CreateFromType(fieldType, reg, true);
                if (fieldTypeSchema.Ref != null)
                {
                    fieldSchema = fieldTypeSchema;
                }
                else
                {
                    // Update
                    if (fieldSchema.Type == null)
                    {
                        fieldSchema.Type = fieldTypeSchema.Type;
                    }

                    if (fieldSchema.Enum == null)
                    {
                        fieldSchema.Enum = fieldTypeSchema.Enum;
                    }

                    if (fieldTypeSchema.Items != null)
                    {
                        var fieldTypeSchemaItems = fieldTypeSchema.Items as JsonSchemaAttribute;
                        if (fieldTypeSchemaItems.Ref != null)
                        {
                            fieldSchema.Items = fieldTypeSchemaItems;
                        }
                        else
                        {
                            if (fieldTypeSchemaItems.Type != null)
                            {
                                var fieldSchemaItems = fieldSchema.Items as JsonSchemaAttribute;
                                if (fieldSchemaItems != null)
                                {
                                    fieldSchemaItems.Type = fieldTypeSchemaItems.Type;
                                }
                                else
                                {
                                    fieldSchema.Items = new JsonSchemaAttribute
                                    {
                                        Type = fieldTypeSchemaItems.Type,
                                    };
                                }
                            }

                            if (fieldTypeSchemaItems.Enum != null)
                            {
                                var fieldSchemaItems = fieldSchema.Items as JsonSchemaAttribute;
                                fieldSchemaItems.Enum = fieldTypeSchemaItems.Enum;
                            }
                        }
                    }
                }

                // Add custom refs to AllOf not to override constrains which already existing.
                var customRef = TypeHelper.GetCustomAttribute <JsonSchemaRefAttribute>(field);
                if (customRef != null)
                {
                    Type schemaBaseType;
                    if (!RefChecker.IsRefTagDerived(customRef.TagType, out schemaBaseType))
                    {
                        throw new ArgumentException("IRefTag<T> must be derived by tagType");
                    }

                    var customSchema = CreateFromType(customRef.TagType, reg, true);
                    switch (customRef.Influence)
                    {
                    case InfluenceRange.Entiry:
                        fieldSchema.AddToAllOf(customSchema);
                        break;

                    case InfluenceRange.AdditionalProperties:
                        if (fieldSchema.AdditionalProperties == null)
                        {
                            fieldSchema.AdditionalProperties = new JsonSchemaAttribute();
                        }
                        fieldSchema.AdditionalProperties.AddToAllOf(customSchema);
                        break;
                    }
                }

                // Add custom refs to AllOf not to override constrains which already existing.
                var customItemsRef = TypeHelper.GetCustomAttribute <ItemsJsonSchemaRefAttribute>(field);
                if (customItemsRef != null)
                {
                    Type schemaBaseType;
                    if (!RefChecker.IsRefTagDerived(customItemsRef.TagType, out schemaBaseType))
                    {
                        throw new ArgumentException("IRefTag<T> must be derived by tagType");
                    }

                    var customSchema = CreateFromType(customItemsRef.TagType, reg, true);
                    switch (customItemsRef.Influence)
                    {
                    case InfluenceRange.Entiry:
                        if (fieldSchema.Items == null)
                        {
                            fieldSchema.Items = new JsonSchemaAttribute();
                        }
                        ((JsonSchemaAttribute)fieldSchema.Items).AddToAllOf(customSchema);
                        break;

                    case InfluenceRange.AdditionalProperties:
                        if (fieldSchema.Items == null)
                        {
                            fieldSchema.Items = new JsonSchemaAttribute();
                        }
                        if (((JsonSchemaAttribute)fieldSchema.Items).AdditionalProperties == null)
                        {
                            ((JsonSchemaAttribute)fieldSchema.Items).AdditionalProperties =
                                new JsonSchemaAttribute();
                        }
                        ((JsonSchemaAttribute)fieldSchema.Items).AdditionalProperties.AddToAllOf(customSchema);
                        break;
                    }
                }

skipField:
                properties.Add(elemName, fieldSchema);
            }

            schema.Properties = properties;
            if (required.Count != 0)
            {
                schema.Required = required.ToArray();
            }
            if (dependencies.Count != 0)
            {
                schema.Dependencies = dependencies;
            }

skip:
            if (asRef)
            {
                return(new JsonSchemaAttribute
                {
                    Ref = schemaId,
                });
            }

            return(schema);
        }
Example #11
0
 public static JsonSchemaAttribute CreateFromClass <T>(JsonSchemaRegistory reg = null, bool asRef = false)
 {
     return(CreateFromType(typeof(T), reg, asRef));
 }