Skip to content

Commit c48f947

Browse files
committed
Bug fix: MultiSearch was returning derived types as base type (as specified in generic)
This fix adds the ConcreteTypeConverter when multiple Types are passed in. Due to my lack of intimate knowledge of how all of the code works, my fix may look a little kludgy/hacky - I wanted to avoid breaking existing functionality with the multisearch - please feel free to revise/clean-up as needed.
1 parent d931a5b commit c48f947

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

src/Nest/Resolvers/Converters/MultiSearchConverter.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,44 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
7171
return multiSearchDescriptor;
7272

7373
var withMeta = docsJarray.Zip(this._descriptor._Operations, (doc, desc) => new MultiHitTuple { Hit = doc, Descriptor = desc });
74+
var originalConverters = serializer.Converters.ToList();
75+
var originalResolver = serializer.ContractResolver;
7476
foreach (var m in withMeta)
7577
{
78+
bool newConverter = false;
79+
if (m.Descriptor.Value._Types != null && m.Descriptor.Value._Types.Count() > 0 && m.Descriptor.Value._Types.Count() > m.Descriptor.Value._Types.Where(x => x.Type == m.Descriptor.Value._ClrType).Count())
80+
{
81+
var typeDict = m.Descriptor.Value._Types.ToDictionary(t => t.Resolve(this._settings), t => t.Type);
82+
Func<dynamic, Hit<dynamic>, Type> typeSelector = (o, h) =>
83+
{
84+
Type t;
85+
if (!typeDict.TryGetValue(h.Type, out t))
86+
return m.Descriptor.Value._ClrType;
87+
return t;
88+
};
89+
serializer.Converters.Clear();
90+
foreach (var orig in originalConverters)
91+
{
92+
if (!(orig is MultiSearchConverter))
93+
serializer.Converters.Add(orig);
94+
}
95+
var converter = new ConcreteTypeConverter(m.Descriptor.Value._ClrType, typeSelector);
96+
serializer.Converters.Add(converter);
97+
serializer.ContractResolver = new ElasticContractResolver(this._settings);
98+
(serializer.ContractResolver as ElasticContractResolver).ConcreteTypeConverter = converter;
99+
newConverter = true;
100+
}
101+
76102
var generic = MakeDelegateMethodInfo.MakeGenericMethod(m.Descriptor.Value._ClrType);
77103
generic.Invoke(null, new object[] { m, serializer, response._Responses, this._settings });
104+
105+
if (newConverter)
106+
{
107+
serializer.Converters.Clear();
108+
serializer.ContractResolver = originalResolver;
109+
foreach (var converter in originalConverters)
110+
serializer.Converters.Add(converter);
111+
}
78112
}
79113

80114
return response;
@@ -85,4 +119,4 @@ public override bool CanConvert(Type objectType)
85119
return objectType == typeof(MultiSearchResponse);
86120
}
87121
}
88-
}
122+
}

0 commit comments

Comments
 (0)