<PackageReference Include="NJsonSchema" Version="10.8.0" />

JsonReferenceResolver

public class JsonReferenceResolver
Resolves JSON Pointer references.
using Namotion.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using NJsonSchema.Infrastructure; using NJsonSchema.References; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; namespace NJsonSchema { public class JsonReferenceResolver { private readonly JsonSchemaAppender _schemaAppender; private readonly Dictionary<string, IJsonReference> _resolvedObjects = new Dictionary<string, IJsonReference>(); public JsonReferenceResolver(JsonSchemaAppender schemaAppender) { _schemaAppender = schemaAppender; } public static Func<JsonSchema, JsonReferenceResolver> CreateJsonReferenceResolverFactory(ITypeNameGenerator typeNameGenerator) { return (JsonSchema schema) => new JsonReferenceResolver(new JsonSchemaAppender(schema, typeNameGenerator)); } public void AddDocumentReference(string documentPath, IJsonReference schema) { _resolvedObjects[documentPath.Contains("://") ? documentPath : DynamicApis.GetFullPath(documentPath)] = schema; } [AsyncStateMachine(typeof(<ResolveReferenceAsync>d__5))] public Task<IJsonReference> ResolveReferenceAsync(object rootObject, string jsonPath, Type targetType, IContractResolver contractResolver, CancellationToken cancellationToken = default(CancellationToken)) { <ResolveReferenceAsync>d__5 stateMachine = default(<ResolveReferenceAsync>d__5); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.rootObject = rootObject; stateMachine.jsonPath = jsonPath; stateMachine.targetType = targetType; stateMachine.contractResolver = contractResolver; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [AsyncStateMachine(typeof(<ResolveReferenceWithoutAppendAsync>d__6))] public Task<IJsonReference> ResolveReferenceWithoutAppendAsync(object rootObject, string jsonPath, Type targetType, IContractResolver contractResolver, CancellationToken cancellationToken = default(CancellationToken)) { <ResolveReferenceWithoutAppendAsync>d__6 stateMachine = default(<ResolveReferenceWithoutAppendAsync>d__6); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.rootObject = rootObject; stateMachine.jsonPath = jsonPath; stateMachine.targetType = targetType; stateMachine.contractResolver = contractResolver; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } public virtual IJsonReference ResolveDocumentReference(object rootObject, string jsonPath, Type targetType, IContractResolver contractResolver) { List<string> segments = jsonPath.Split(new char[1] { '/' }).Skip(1).ToList(); IJsonReference jsonReference = ResolveDocumentReference(rootObject, segments, targetType, contractResolver, new HashSet<object>()); if (jsonReference == null) throw new InvalidOperationException("Could not resolve the path '" + jsonPath + "'."); return jsonReference; } [AsyncStateMachine(typeof(<ResolveFileReferenceAsync>d__8))] public virtual Task<IJsonReference> ResolveFileReferenceAsync(string filePath, CancellationToken cancellationToken = default(CancellationToken)) { <ResolveFileReferenceAsync>d__8 stateMachine = default(<ResolveFileReferenceAsync>d__8); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.filePath = filePath; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [AsyncStateMachine(typeof(<ResolveUrlReferenceAsync>d__9))] public virtual Task<IJsonReference> ResolveUrlReferenceAsync(string url, CancellationToken cancellationToken = default(CancellationToken)) { <ResolveUrlReferenceAsync>d__9 stateMachine = default(<ResolveUrlReferenceAsync>d__9); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.url = url; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [AsyncStateMachine(typeof(<ResolveReferenceAsync>d__10))] private Task<IJsonReference> ResolveReferenceAsync(object rootObject, string jsonPath, Type targetType, IContractResolver contractResolver, bool append, CancellationToken cancellationToken = default(CancellationToken)) { <ResolveReferenceAsync>d__10 stateMachine = default(<ResolveReferenceAsync>d__10); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.rootObject = rootObject; stateMachine.jsonPath = jsonPath; stateMachine.targetType = targetType; stateMachine.contractResolver = contractResolver; stateMachine.append = append; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } public virtual string ResolveFilePath(string documentPath, string jsonPath) { string[] array = Regex.Split(jsonPath, "(?=#)"); return DynamicApis.PathCombine(DynamicApis.PathGetDirectoryName(documentPath), array[0]); } [AsyncStateMachine(typeof(<ResolveFileReferenceWithAlreadyResolvedCheckAsync>d__12))] private Task<IJsonReference> ResolveFileReferenceWithAlreadyResolvedCheckAsync(string filePath, Type targetType, IContractResolver contractResolver, string jsonPath, bool append, CancellationToken cancellationToken) { <ResolveFileReferenceWithAlreadyResolvedCheckAsync>d__12 stateMachine = default(<ResolveFileReferenceWithAlreadyResolvedCheckAsync>d__12); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.filePath = filePath; stateMachine.targetType = targetType; stateMachine.contractResolver = contractResolver; stateMachine.jsonPath = jsonPath; stateMachine.append = append; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [AsyncStateMachine(typeof(<ResolveUrlReferenceWithAlreadyResolvedCheckAsync>d__13))] private Task<IJsonReference> ResolveUrlReferenceWithAlreadyResolvedCheckAsync(string fullJsonPath, string jsonPath, Type targetType, IContractResolver contractResolver, bool append, CancellationToken cancellationToken) { <ResolveUrlReferenceWithAlreadyResolvedCheckAsync>d__13 stateMachine = default(<ResolveUrlReferenceWithAlreadyResolvedCheckAsync>d__13); stateMachine.<>t__builder = AsyncTaskMethodBuilder<IJsonReference>.Create(); stateMachine.<>4__this = this; stateMachine.fullJsonPath = fullJsonPath; stateMachine.jsonPath = jsonPath; stateMachine.targetType = targetType; stateMachine.contractResolver = contractResolver; stateMachine.append = append; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } private IJsonReference ResolveDocumentReference(object obj, List<string> segments, Type targetType, IContractResolver contractResolver, HashSet<object> checkedObjects) { if (obj == null || obj is string || checkedObjects.Contains(obj)) return null; IJsonReference jsonReference = obj as IJsonReference; if (jsonReference != null && jsonReference.Reference != null) { IJsonReference jsonReference2 = ResolveDocumentReferenceWithoutDereferencing(jsonReference.Reference, segments, targetType, contractResolver, checkedObjects); if (jsonReference2 == null) return ResolveDocumentReferenceWithoutDereferencing(obj, segments, targetType, contractResolver, checkedObjects); return jsonReference2; } return ResolveDocumentReferenceWithoutDereferencing(obj, segments, targetType, contractResolver, checkedObjects); } private IJsonReference ResolveDocumentReferenceWithoutDereferencing(object obj, List<string> segments, Type targetType, IContractResolver contractResolver, HashSet<object> checkedObjects) { if (segments.Count == 0) { if (obj is IDictionary) { JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = contractResolver }; string value = JsonConvert.SerializeObject(obj, settings); return (IJsonReference)JsonConvert.DeserializeObject(value, targetType, settings); } return (IJsonReference)obj; } checkedObjects.Add(obj); string text = segments[0]; IDictionary dictionary = obj as IDictionary; if (dictionary != null) { if (dictionary.Contains(text)) return ResolveDocumentReference(dictionary[text], segments.Skip(1).ToList(), targetType, contractResolver, checkedObjects); } else if (obj is IEnumerable) { if (int.TryParse(text, out int result)) { object[] array = ((IEnumerable)obj).Cast<object>().ToArray(); if (array.Length > result) return ResolveDocumentReference(array[result], segments.Skip(1).ToList(), targetType, contractResolver, checkedObjects); } } else { IJsonExtensionObject jsonExtensionObject = obj as IJsonExtensionObject; if (jsonExtensionObject != null) { bool? nullable = jsonExtensionObject.ExtensionData?.ContainsKey(text); bool flag = true; if ((nullable.GetValueOrDefault() == flag) & nullable.HasValue) return ResolveDocumentReference(jsonExtensionObject.ExtensionData[text], segments.Skip(1).ToList(), targetType, contractResolver, checkedObjects); } foreach (ContextualAccessorInfo item in from p in ContextualTypeExtensions.GetContextualAccessors(obj.GetType()) where p.get_AccessorType().GetInheritedAttribute<JsonIgnoreAttribute>() == null select p) { string name = item.GetName(); if (name == text) { object value2 = item.GetValue(obj); return ResolveDocumentReference(value2, segments.Skip(1).ToList(), targetType, contractResolver, checkedObjects); } } } return null; } } }