public virtual JsonSchema NewField(string name, Type parentType, object pInstance = null, JToken jpInstance = null) { MemberInfo model = parentType?.GetMember(name).First(); Type modelType = GetModelType(model); JTokenType jTokenType = ToJTokenType(modelType, jpInstance); AssertV2.IsNotNull(jTokenType, "jTokenType"); JsonSchema newField = new JsonSchema() { type = jTokenType.ToJsonSchemaType(), title = JsonSchema.ToTitle(name) }; ExtractFieldDocu(newField, model, modelType, jTokenType, pInstance, jpInstance); if (model != null) { if (!model.CanWriteTo()) { newField.readOnly = true; } if (model.TryGetCustomAttribute(out RegexAttribute attr)) { newField.pattern = attr.regex; } if (model.TryGetCustomAttribute(out ContentAttribute c)) { newField.format = "" + c.type; } if (model.TryGetCustomAttribute(out MinMaxRangeAttribute ra)) { newField.minimum = ra.minimum; newField.maximum = ra.maximum; } if (model.TryGetCustomAttribute(out InputLengthAttribute ila)) { if (ila.minLength > 0) { newField.minLength = ila.minLength; } if (ila.maxLength > 0) { newField.maxLength = ila.maxLength; } } if (model.TryGetCustomAttribute(out EnumAttribute e)) { newField.contentEnum = e.names; newField.additionalItems = e.allowOtherInput; } if (model.TryGetCustomAttribute(out RequiredAttribute r)) { newField.mandatory = true; } if (model.TryGetCustomAttribute(out JsonPropertyAttribute p)) { if (p.Required == Required.Always || p.Required == Required.DisallowNull) { newField.mandatory = true; } } if (modelType.IsEnum) { newField.contentEnum = Enum.GetNames(modelType); } } if (jTokenType == JTokenType.Object) { if (modelType == null) { newField.properties = new Dictionary <string, JsonSchema>(); AddFieldsViaJson(newField, null, jpInstance as JObject); } else { var modelInstance = pInstance != null?model.GetValue(pInstance) : null; SetupInnerJsonSchema(newField, modelType, modelInstance); } } if (jTokenType == JTokenType.Array) { var listElemType = GetListElementType(modelType); var arrayElemJType = ToJTokenType(listElemType); if (arrayElemJType == JTokenType.Null) { if (jpInstance is JArray a && a.Count > 0) { arrayElemJType = a.First.Type; } } if (arrayElemJType != JTokenType.Null) { if (!IsSimpleType(arrayElemJType)) { var childrenInstances = GetChildrenArray(pInstance, jpInstance, model); if (childrenInstances == null || AllChildrenHaveSameType(childrenInstances)) { var firstChildInstance = childrenInstances?.FirstOrDefault(); var childVm = new JsonSchema() { type = arrayElemJType.ToJsonSchemaType() }; SetupInnerJsonSchema(childVm, listElemType, firstChildInstance); newField.items = new List <JsonSchema>() { childVm }; } else { newField.items = new List <JsonSchema>(); foreach (var child in childrenInstances) { var childVm = new JsonSchema() { type = arrayElemJType.ToJsonSchemaType() }; SetupInnerJsonSchema(childVm, child.GetType(), child); newField.items.Add(childVm); } AssertV2.AreEqual(childrenInstances.Length, newField.items.Count); } } else { newField.items = new List <JsonSchema>() { new JsonSchema() { type = arrayElemJType.ToJsonSchemaType() } }; } } } return(newField); }