Upgrade to NEST 7.0 serializer issues.
See original GitHub issueI upgraded to elasticsearch 7 from 5 and one area that bit me and caused me about a days worth of work was trying to figure out why my models were not being serialized correctly. I was under the impression that in 7.0 that all serializer settings configured were only for my models and that was it. This is where I went wrong…
I injected my applications serializer settings and configured it like this thinking it would use all my serializer settings:
var settings = new ConnectionSettings(connectionPool,
(serializer, values) => new JsonNetSerializer(serializer, values, () => _myAppsInjectedSerializerSettings));
After a day of messing around and creating smaller and smaller samples, I found that my injected serializer settings were modified by reference and affected my entire application (NOT Cool). I believe this is being done so NEST Attributes can be resolved (of which we don’t use anywhere in our app and have no plans todo). So I was able to rework the following in one of our apps which got us up and working:
var settings = new ConnectionSettings(
CreateConnectionPool() ?? new SingleNodeConnectionPool(new Uri(_config.ConnectionString)),
(serializer, values) => new JsonNetSerializer(serializer, values, JsonSerializerSettingsFactory, ModifyContactResolver, ContractJsonConverters));
private JsonSerializerSettings JsonSerializerSettingsFactory()
{
return new JsonSerializerSettings
{
DateParseHandling = _serializerSettings.DateParseHandling,
DefaultValueHandling = _serializerSettings.DefaultValueHandling,
MissingMemberHandling = _serializerSettings.MissingMemberHandling,
NullValueHandling = _serializerSettings.NullValueHandling
};
}
private void ModifyContactResolver(ConnectionSettingsAwareContractResolver resolver)
{
var strategy = ((DefaultContractResolver) _serializerSettings.ContractResolver).NamingStrategy;
resolver.NamingStrategy = new CamelCaseNamingStrategy(strategy.ProcessDictionaryKeys, strategy.OverrideSpecifiedNames, strategy.ProcessExtensionDataNames);
}
private IEnumerable<JsonConverter> ContractJsonConverters => _serializerSettings.Converters;
One of my main concerns about this is that I don’t like that I can’t just use my existing serializer settings and there probably is a lot of properties that I’m not syncing… I’d rather just inject my settings and know it’s the same exact serializer settings. Which brings me to my blocking issue.
In Exceptionless, we have a custom contract resolver that depending on the type we use one serializer or the other (here is where we register the serializer). I don’t even know how I’d modify the contract resolver in this case. I could probably get 80% of the way there with a custom naming strategy but we do custom logic in LowerCaseUnderscorePropertyNamesContractResolver.CreateProperty
.
Is there a good way to solve this?
Issue Analytics
- State:
- Created 4 years ago
- Comments:11 (11 by maintainers)
Top GitHub Comments
Thats correct:
Nest.JsonNetSerializer
exists to deal with bits from NET in your source documents such asIf neither apply it could be more beneficial to create your own
IElasticsearchSerializer
based onJson.Net
and return that from thesource serializer
factory method you pass toConnectionSettings
. That way we don’t bleed into your existing contract resolvers.This looks like a manifestation of the recurrent problem that the client needs to make specific modifications to the serializer settings, including the
IContractResolver
, that could collide with your changes to the serializer settings needed for your application.You may need to derive from
JsonNetSerializer
and overrideCreateContractResolver()
to return anIContractResolver
that derives fromConnectionSettingsAwareContractResolver
which applies any settings that you need, or calls to the base implementation.I would like to revisit this implementation for 8.x, to see if it’s possible to make these components easier to use and modify.