Serialization error in NEST in MultiSearch API


(Kirill Teplinskiy) #1

Hi!

I have updated NEST from 2.4.3 to 2.4.4 and .MultiSearch calls began to throw UnexpectedElasticsearchClientException. The issue appears only in v2.4.4 and I can't reproduce it in v2.4.3, v2.4.5 or v2.4.6. However, the issue isn't mentioned in release notes for 2.4.5 so it may be kind of accidental break that was accidentally fixed in v2.4.5. It would be great to know for sure if this error was completely fixed in v2.4.5 or not :slight_smile:

So this is minimal code to reproduce the error. The essential conditions to reproduce the error is to build a query against interface with .Search<ITestDocument>() and setting the actual type with .Type<>():

class Program
{
    static void Main(string[] args)
    {
        var client = new ElasticClient(new Uri("http://localhost:9200"));

        client.Index(new TestDocument {Id = "1"}, s => s.Index("testdoc"));
        var r = client.MultiSearch(ms => ms.Search<ITestDocument>("f", s => s.MatchAll().Type<TestDocument>().Index("testdoc")));
    }
}

public class TestDocument : ITestDocument
{
    public string Id { get; set; }
}

public interface ITestDocument
{
}

And this is error message (complete message):

Unhandled Exception: Elasticsearch.Net.UnexpectedElasticsearchClientException: Object of type 'Nest.JsonNetSerializer' cannot be converted to type 'Newtonsoft.Json.JsonSerializer'. ---> System.ArgumentException: Object of type 'Nest.JsonNetSerializer' cannot be converted to type 'Newtonsoft.Json.JsonSerializer'.
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Nest.MultiSearchResponseJsonConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) in C:\code\elasticsearch-net\src\Nest\Search\MultiSearch\MultiSearchResponseJsonConverter.cs:line 67

...


(Russ Cam) #2

Hey @Kirill_Teplinskiy,

This change (and exception) sneaked in as part of a refactoring for how to set serializer settings within https://github.com/elastic/elasticsearch-net/pull/2197 . As part of that PR, the creation of serializers that hold state used at the point of deserialization, was pushed down onto ConnectionSettings and in this specific instance, a check was missing to ensure that the serializer constructed is one that derives from Json.NET's serializer.

The good news is that this is fixed in 2.4.5+ and in fact, the performance of multisearch responses is much improved over 2.4.4. I would always recommend updating to the latest major version of NEST e.g. 2.x -> 2.4.6 currently.

Hope that helps :smiley:


(Kirill Teplinskiy) #3

@forloop Yes, thank you! Of course, I updated to the latest v2.4.6 now.


(system) #4