public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (this._settings == null) { var realConverter = serializer.GetStatefulConverter <MultiSearchResponseJsonConverter>(); var mr = realConverter.ReadJson(reader, objectType, existingValue, serializer) as MultiSearchResponse; return(mr); } var response = new MultiSearchResponse(); var jsonObject = JObject.Load(reader); var docsJarray = (JArray)jsonObject["responses"]; if (docsJarray == null) { return(response); } var multiSearchDescriptor = this._request; if (this._request == null) { return(multiSearchDescriptor); } var withMeta = docsJarray.Zip(this._request.Operations, (doc, desc) => new MultiHitTuple { Hit = doc, Descriptor = desc }); var originalResolver = serializer.ContractResolver; foreach (var m in withMeta) { var descriptor = m.Descriptor.Value; var concreteTypeSelector = descriptor.TypeSelector; var baseType = m.Descriptor.Value.ClrType ?? typeof(object); var generic = MakeDelegateMethodInfo.MakeGenericMethod(baseType); if (concreteTypeSelector != null) { var state = typeof(ConcreteTypeConverter <>).CreateGenericInstance(baseType, concreteTypeSelector) as JsonConverter; if (state != null) { var elasticSerializer = new JsonNetSerializer(this._settings, state); generic.Invoke(null, new object[] { m, elasticSerializer.Serializer, response.Responses, this._settings }); continue; } } generic.Invoke(null, new object[] { m, serializer, response.Responses, this._settings }); } return(response); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (this._settings == null) { var realConverter = serializer.GetStatefulConverter <MultiSearchResponseJsonConverter>(); return(realConverter.ReadJson(reader, objectType, existingValue, serializer)); } var response = new MultiSearchResponse(); var jsonObject = JObject.Load(reader); var docsJarray = (JArray)jsonObject["responses"]; if (docsJarray == null) { return(response); } var multiSearchDescriptor = this._request; if (this._request == null) { return(multiSearchDescriptor); } IEnumerable <SearchHitTuple> withMeta; if (this._request is IMultiSearchRequest multiSearch) { withMeta = docsJarray.Zip(multiSearch.Operations, (doc, desc) => new SearchHitTuple { Hit = doc, Descriptor = new KeyValuePair <string, ICovariantSearchRequest>(desc.Key, desc.Value) }); } else { if (!(this._request is IMultiSearchTemplateRequest multiSearchTemplate)) { throw new InvalidOperationException($"Request must be an instance of {nameof(IMultiSearchRequest)} or {nameof(IMultiSearchTemplateRequest)}"); } withMeta = docsJarray.Zip(multiSearchTemplate.Operations, (doc, desc) => new SearchHitTuple { Hit = doc, Descriptor = new KeyValuePair <string, ICovariantSearchRequest>(desc.Key, desc.Value) }); } foreach (var m in withMeta) { var descriptor = m.Descriptor.Value; var concreteTypeSelector = descriptor.TypeSelector; var baseType = m.Descriptor.Value.ClrType ?? typeof(object); var cachedDelegate = serializer.GetConnectionSettings().Inferrer.CreateSearchResponseDelegates.GetOrAdd(baseType, t => { // Compile a delegate from an expression var methodInfo = MakeDelegateMethodInfo.MakeGenericMethod(t); var tupleParameter = Expression.Parameter(typeof(SearchHitTuple), "tuple"); var serializerParameter = Expression.Parameter(typeof(JsonSerializer), "serializer"); var multiHitCollection = Expression.Parameter(typeof(IDictionary <string, object>), "collection"); var parameterExpressions = new[] { tupleParameter, serializerParameter, multiHitCollection }; var call = Expression.Call(null, methodInfo, parameterExpressions); var lambda = Expression.Lambda <Action <SearchHitTuple, JsonSerializer, IDictionary <string, object> > >(call, parameterExpressions); return(lambda.Compile()); }); if (concreteTypeSelector != null) { var state = (JsonConverter)typeof(ConcreteTypeConverter <>).CreateGenericInstance(baseType, concreteTypeSelector); if (state != null) { var elasticSerializer = this._settings.CreateStateful(state); if (elasticSerializer != null) { cachedDelegate(m, elasticSerializer.Serializer, response.Responses); continue; } } } cachedDelegate(m, serializer, response.Responses); } return(response); }