Skip to content

Commit cadcaa9

Browse files
committed
added propertyname inferrer to IConnectionSettings so you can override how NEST handles unspecified propertynames without supplying your own JsonContractResolver
1 parent e4def2d commit cadcaa9

File tree

11 files changed

+96
-124
lines changed

11 files changed

+96
-124
lines changed

src/Nest.Tests.Unit/Core/Index/IndexTests.cs

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,40 @@
1313

1414
namespace Nest.Tests.Unit.Core.Index
1515
{
16-
[TestFixture]
17-
public class IndexTests : BaseJsonTests
18-
{
19-
[Test]
20-
public void IndexParameters()
21-
{
22-
var o = new ElasticSearchProject { Id = 1, Name = "Test" };
23-
var result = this._client.Index(o, new IndexParameters
24-
{
25-
Version = "1",
16+
[TestFixture]
17+
public class IndexTests : BaseJsonTests
18+
{
19+
[Test]
20+
public void IndexParameters()
21+
{
22+
var o = new ElasticSearchProject { Id = 1, Name = "Test" };
23+
var result = this._client.Index(o, new IndexParameters
24+
{
25+
Version = "1",
26+
});
27+
var status = result.ConnectionStatus;
28+
StringAssert.Contains("version=1", status.RequestUrl);
29+
}
2630

27-
});
28-
var status = result.ConnectionStatus;
29-
StringAssert.Contains("version=1", status.RequestUrl);
30-
}
31-
32-
[Test]
33-
public void IndexingDictionaryRespectsCasing()
34-
{
35-
var x = new
36-
{
37-
FirstDictionary = new Dictionary<string, object>
31+
[Test]
32+
public void IndexingDictionaryRespectsCasing()
33+
{
34+
var x = new
35+
{
36+
FirstDictionary = new Dictionary<string, object>
3837
{
3938
{"ALLCAPS", 1 },
4039
{"PascalCase", "should work as well"},
4140
{"camelCase", DateTime.Now}
4241
}
43-
};
44-
var result = this._client.Index(x);
42+
};
43+
var result = this._client.Index(x);
4544

46-
var request = result.ConnectionStatus.Request;
47-
StringAssert.Contains("ALLCAPS", request);
48-
StringAssert.Contains("PascalCase", request);
49-
StringAssert.Contains("camelCase", request);
50-
StringAssert.Contains("firstDictionary", request);
51-
52-
}
53-
}
45+
var request = result.ConnectionStatus.Request;
46+
StringAssert.Contains("ALLCAPS", request);
47+
StringAssert.Contains("PascalCase", request);
48+
StringAssert.Contains("camelCase", request);
49+
StringAssert.Contains("firstDictionary", request);
50+
}
51+
}
5452
}

src/Nest/Domain/Connection/ConnectionSettings.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public string DefaultIndex
3535
public FluentDictionary<Type, string> DefaultIndices { get; private set; }
3636
public FluentDictionary<Type, string> DefaultTypeNames { get; private set; }
3737
public NameValueCollection QueryStringParameters { get; private set; }
38+
public Func<string, string> DefaultPropertyNameInferrer { get; private set; }
3839

3940
public ConnectionSettings(Uri uri)
4041
{
@@ -160,6 +161,19 @@ private void ConnectionStatusDefaultHandler(ConnectionStatus status)
160161
return;
161162
}
162163

164+
/// <summary>
165+
/// By default NEST camelCases property names (EmailAddress => emailAddress) that do not have an explicit propertyname
166+
/// either via an ElasticProperty attribute or because they are part of Dictionary where the keys should be treated verbatim.
167+
/// <pre>
168+
/// Here you can register a function that transforms propertynames (default casing, pre- or suffixing)
169+
/// </pre>
170+
/// </summary>
171+
public ConnectionSettings SetDefaultPropertyNameInferrer(Func<string, string> propertyNameSelector)
172+
{
173+
this.DefaultPropertyNameInferrer = propertyNameSelector;
174+
return this;
175+
}
176+
163177
public ConnectionSettings SetDefaultTypeNameInferrer(Func<Type, string> defaultTypeNameInferrer)
164178
{
165179
defaultTypeNameInferrer.ThrowIfNull("defaultTypeNameInferrer");
@@ -187,5 +201,6 @@ public ConnectionSettings MapDefaultTypeNames(Action<FluentDictionary<Type, stri
187201
return this;
188202
}
189203

190-
}
204+
205+
}
191206
}
Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1-
using System;
1+
using System;
22
using System.Collections.Specialized;
3-
4-
namespace Nest
5-
{
6-
public interface IConnectionSettings
7-
{
8-
FluentDictionary<Type, string> DefaultIndices { get; }
9-
FluentDictionary<Type, string> DefaultTypeNames { get; }
10-
string DefaultIndex { get; }
113

12-
Uri Uri { get; }
13-
int MaximumAsyncConnections { get; }
14-
string Host { get; }
15-
int Port { get; }
16-
int Timeout { get; }
17-
string ProxyAddress { get; }
18-
string ProxyUsername { get; }
19-
string ProxyPassword { get; }
20-
21-
bool TraceEnabled { get; }
22-
bool DontDoubleEscapePathDotsAndSlashes { get; }
23-
NameValueCollection QueryStringParameters { get; }
24-
Action<ConnectionStatus> ConnectionStatusHandler { get; }
4+
namespace Nest
5+
{
6+
public interface IConnectionSettings
7+
{
8+
FluentDictionary<Type, string> DefaultIndices { get; }
9+
FluentDictionary<Type, string> DefaultTypeNames { get; }
10+
string DefaultIndex { get; }
2511

26-
Func<Type, string> DefaultTypeNameInferrer { get; }
27-
}
28-
}
12+
Uri Uri { get; }
13+
int MaximumAsyncConnections { get; }
14+
string Host { get; }
15+
int Port { get; }
16+
int Timeout { get; }
17+
string ProxyAddress { get; }
18+
string ProxyUsername { get; }
19+
string ProxyPassword { get; }
20+
21+
bool TraceEnabled { get; }
22+
bool DontDoubleEscapePathDotsAndSlashes { get; }
23+
NameValueCollection QueryStringParameters { get; }
24+
Action<ConnectionStatus> ConnectionStatusHandler { get; }
25+
26+
Func<string, string> DefaultPropertyNameInferrer { get; }
27+
28+
Func<Type, string> DefaultTypeNameInferrer { get; }
29+
}
30+
}

src/Nest/ElasticSerializer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public T Deserialize<T>(string value, IEnumerable<JsonConverter> extraConverters
108108
var concrete = extraConverters.OfType<ConcreteTypeConverter>().FirstOrDefault();
109109
if (concrete != null)
110110
{
111-
((ElasticResolver)settings.ContractResolver).ConcreteTypeConverter = concrete;
111+
((ElasticContractResolver)settings.ContractResolver).ConcreteTypeConverter = concrete;
112112
}
113113
else
114114
settings.Converters = settings.Converters.Concat(extraConverters).ToList();
@@ -120,7 +120,7 @@ private JsonSerializerSettings CreateSettings()
120120
{
121121
return new JsonSerializerSettings()
122122
{
123-
ContractResolver = new ElasticCamelCaseResolver(this._settings),
123+
ContractResolver = new ElasticContractResolver(this._settings),
124124
NullValueHandling = NullValueHandling.Ignore,
125125
DefaultValueHandling = DefaultValueHandling.Include,
126126
Converters = _defaultConverters.Concat(_extraConverters).ToList()

src/Nest/Nest.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@
539539
<Compile Include="DSL\Query\Term.cs" />
540540
<Compile Include="DSL\Query\Wildcard.cs" />
541541
<Compile Include="ElasticClient-Search.cs" />
542-
<Compile Include="Resolvers\ElasticSearchJsonResolver.cs" />
542+
<Compile Include="Resolvers\ElasticContractResolver.cs" />
543543
<Compile Include="Enums\Consistency.cs" />
544544
<Compile Include="Enums\FacetTypes.cs" />
545545
<Compile Include="Enums\Replication.cs" />

src/Nest/RawElasticClient.cs

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,71 +13,29 @@ namespace Nest
1313
{
1414
public partial class RawElasticClient : IRawElasticClient
1515
{
16-
protected IConnection Connection { get; set; }
16+
public IConnection Connection { get; protected set; }
1717
public IConnectionSettings Settings { get; protected set; }
18+
public ElasticSerializer Serializer { get; protected set; }
1819

1920
public RawElasticClient(IConnectionSettings settings)
2021
: this(settings, new Connection(settings))
2122
{
2223

2324
}
2425

25-
internal readonly JsonSerializerSettings SerializationSettings;
26-
internal readonly JsonSerializerSettings IndexSerializationSettings;
27-
internal readonly PropertyNameResolver PropertyNameResolver;
28-
private readonly List<JsonConverter> _extraConverters = new List<JsonConverter>();
29-
30-
private readonly List<JsonConverter> _defaultConverters = new List<JsonConverter>
31-
{
32-
new IsoDateTimeConverter(),
33-
new FacetConverter()
34-
};
35-
36-
private JsonSerializerSettings CreateSettings()
37-
{
38-
return new JsonSerializerSettings()
39-
{
40-
ContractResolver = new ElasticResolver(this.Settings),
41-
NullValueHandling = NullValueHandling.Ignore,
42-
DefaultValueHandling = DefaultValueHandling.Include,
43-
Converters = _defaultConverters.Concat(_extraConverters).ToList()
44-
};
45-
}
46-
public void AddConverter(JsonConverter converter)
47-
{
48-
this.IndexSerializationSettings.Converters.Add(converter);
49-
this.SerializationSettings.Converters.Add(converter);
50-
_extraConverters.Add(converter);
51-
}
52-
53-
public void ModifyJsonSerializationSettings(Action<JsonSerializerSettings> modifier)
54-
{
55-
modifier(this.IndexSerializationSettings);
56-
modifier(this.SerializationSettings);
57-
}
58-
59-
/// <summary>
60-
/// serialize an object using the internal registered converters without camelcasing properties as is done
61-
/// while indexing objects
62-
/// </summary>
63-
public string Serialize(object @object)
64-
{
65-
return JsonConvert.SerializeObject(@object, Formatting.Indented, this.SerializationSettings);
66-
}
67-
6826
public RawElasticClient(IConnectionSettings settings, IConnection connection)
6927
{
7028
if (settings == null)
7129
throw new ArgumentNullException("settings");
7230

7331
this.Settings = settings;
7432
this.Connection = connection;
33+
this.Serializer = new ElasticSerializer(this.Settings);
34+
}
7535

76-
this.SerializationSettings = this.CreateSettings();
77-
var indexSettings = this.CreateSettings();
78-
79-
indexSettings.ContractResolver = new ElasticCamelCaseResolver(this.Settings);
80-
this.IndexSerializationSettings = indexSettings;
36+
public string Serialize(object @object)
37+
{
38+
return this.Serializer.Serialize(@object);
8139
}
8240

8341
protected ConnectionStatus DoRequest(string method, string path, object data = null, NameValueCollection queryString = null)

src/Nest/Resolvers/Converters/ConcreteTypeConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public ConcreteTypeConverter(Type baseType, Func<dynamic, Hit<dynamic>, Type> co
3232

3333
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
3434
{
35-
var realConcreteConverter = ((ElasticResolver) serializer.ContractResolver).ConcreteTypeConverter;
35+
var realConcreteConverter = ((ElasticContractResolver) serializer.ContractResolver).ConcreteTypeConverter;
3636

3737
if (realConcreteConverter != null)
3838
{

src/Nest/Resolvers/Converters/IndexNameMarkerConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
2323
return;
2424
}
2525

26-
var settings = serializer.ContractResolver as ElasticResolver;
26+
var settings = serializer.ContractResolver as ElasticContractResolver;
2727
if (settings != null && settings.ConnectionSettings != null)
2828
{
2929
var typeName = marker.Resolve(settings.ConnectionSettings);

src/Nest/Resolvers/Converters/IndexSettingsConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
105105
writer.WriteEndObject();
106106
if (indexSettings.Mappings.Count > 0)
107107
{
108-
var settings = serializer.ContractResolver as ElasticResolver;
108+
var settings = serializer.ContractResolver as ElasticContractResolver;
109109
if (settings != null && settings.ConnectionSettings != null)
110110
{
111111
writer.WritePropertyName("mappings");

src/Nest/Resolvers/Converters/TypeNameMarkerConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
2222
writer.WriteNull();
2323
return;
2424
}
25-
var settings = serializer.ContractResolver as ElasticResolver;
25+
var settings = serializer.ContractResolver as ElasticContractResolver;
2626
if (settings != null && settings.ConnectionSettings != null)
2727
{
2828
var typeName = marker.Resolve(settings.ConnectionSettings);

src/Nest/Resolvers/ElasticSearchJsonResolver.cs renamed to src/Nest/Resolvers/ElasticContractResolver.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Nest.Resolvers
1212
{
13-
public class ElasticResolver : DefaultContractResolver
13+
public class ElasticContractResolver : DefaultContractResolver
1414
{
1515
/// <summary>
1616
/// ConnectionSettings can be requested by JsonConverter's.
@@ -23,11 +23,19 @@ public class ElasticResolver : DefaultContractResolver
2323
/// </summary>
2424
internal ConcreteTypeConverter ConcreteTypeConverter { get; set; }
2525

26-
public ElasticResolver(IConnectionSettings connectionSettings) : base(true)
26+
public ElasticContractResolver(IConnectionSettings connectionSettings) : base(true)
2727
{
2828
this.ConnectionSettings = connectionSettings;
2929
}
3030

31+
protected override string ResolvePropertyName(string propertyName)
32+
{
33+
if (this.ConnectionSettings.DefaultPropertyNameInferrer != null)
34+
return this.ConnectionSettings.DefaultPropertyNameInferrer(propertyName);
35+
36+
return propertyName.ToCamelCase();
37+
}
38+
3139
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
3240
{
3341
var property = base.CreateProperty(member, memberSerialization);
@@ -45,13 +53,4 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
4553
}
4654

4755
}
48-
public class ElasticCamelCaseResolver : ElasticResolver
49-
{
50-
public ElasticCamelCaseResolver(IConnectionSettings connectionSettings) : base(connectionSettings) { }
51-
52-
protected override string ResolvePropertyName(string propertyName)
53-
{
54-
return propertyName.ToCamelCase();
55-
}
56-
}
5756
}

0 commit comments

Comments
 (0)