Skip to content

Commit b9afe19

Browse files
committed
Use serializer when deserializing LazyDocument to T
When converting a LazyDocument to type T, use the JsonNetSerializer configured, along with all registered contract resolvers. Fixes #2788
1 parent 9b0d36b commit b9afe19

File tree

4 files changed

+109
-11
lines changed

4 files changed

+109
-11
lines changed

src/Nest/CommonAbstractions/LazyDocument/LazyDocument.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ public interface ILazyDocument
1717
public class LazyDocument : ILazyDocument
1818
{
1919
internal JToken _Value { get; set; }
20+
internal JsonSerializer _Serializer { get; set; }
2021

2122
public T As<T>() where T : class
2223
{
2324
var jToken = this._Value;
24-
return jToken?.ToObject<T>();
25+
return jToken?.ToObject<T>(_Serializer);
2526
}
2627
}
2728
}

src/Nest/CommonAbstractions/LazyDocument/LazyDocumentJsonConverter.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,24 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
1010
{
1111
var d = value as LazyDocument;
1212
if (d?._Value == null)
13+
{
14+
writer.WriteNull();
1315
return;
16+
}
17+
1418
writer.WriteToken(d._Value.CreateReader());
1519
}
1620

1721
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
1822
{
1923
var document = serializer.Deserialize(reader) as JToken;
20-
return new LazyDocument { _Value = document };
24+
return new LazyDocument
25+
{
26+
_Value = document,
27+
_Serializer = serializer
28+
};
2129
}
2230

23-
public override bool CanConvert(Type objectType)
24-
{
25-
return true;
26-
}
31+
public override bool CanConvert(Type objectType) => true;
2732
}
2833
}

src/Nest/Search/Search/Hits/InnerHitsResult.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ namespace Nest
66
{
77
public class InnerHitsResult
88
{
9-
109
[JsonProperty("hits")]
1110
public InnerHitsMetaData Hits { get; internal set; }
1211

13-
public IEnumerable<T> Documents<T>() where T : class
14-
{
15-
return this.Hits == null ? Enumerable.Empty<T>() : this.Hits.Documents<T>();
16-
}
12+
/// <summary>
13+
/// Retrieve <see cref="Hits"/> documents as a strongly typed
14+
/// collection
15+
/// </summary>
16+
/// <typeparam name="T">The hits document type</typeparam>
17+
public IEnumerable<T> Documents<T>() where T : class =>
18+
this.Hits == null ? Enumerable.Empty<T>() : this.Hits.Documents<T>();
1719
}
1820
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using System.Linq;
3+
using Elasticsearch.Net;
4+
using FluentAssertions;
5+
using FluentAssertions.Common;
6+
using Nest;
7+
using Tests.Framework;
8+
using Tests.Framework.ManagedElasticsearch.Clusters;
9+
using Xunit;
10+
11+
namespace Tests.Reproduce
12+
{
13+
public class GithubIssue2788 : IClusterFixture<WritableCluster>
14+
{
15+
private readonly WritableCluster _cluster;
16+
17+
public GithubIssue2788(WritableCluster cluster)
18+
{
19+
_cluster = cluster;
20+
}
21+
22+
// sample mapping with nested objects with TimeSpan field
23+
class Root
24+
{
25+
[Nested]
26+
public Child[] Children { get; set; }
27+
}
28+
29+
class Child
30+
{
31+
public TimeSpan StartTime { get; set; }
32+
33+
public TimeSpan EndTime { get; set; }
34+
}
35+
36+
[I]
37+
public void CanDeserializeNumberToTimeSpanInInnerHits()
38+
{
39+
var indexName = "sample";
40+
var client = _cluster.Client;
41+
42+
//create index with automapping
43+
client.CreateIndex(indexName, create => create
44+
.Mappings(mappings => mappings
45+
.Map<Root>(map => map
46+
.AutoMap()
47+
)
48+
)
49+
);
50+
51+
var startTime = new TimeSpan(1, 2, 3);
52+
var endTime = new TimeSpan(2, 3, 4);
53+
54+
client.Index(new Root
55+
{
56+
Children = new[]
57+
{
58+
new Child
59+
{
60+
StartTime = startTime,
61+
EndTime = endTime
62+
63+
}
64+
}
65+
}, index => index
66+
.Index(indexName)
67+
.Refresh(Refresh.WaitFor)
68+
);
69+
70+
var result = client.Search<Root>(search => search
71+
.Query(query => query
72+
.Nested(nested => nested
73+
.Query(nestedQuery => nestedQuery
74+
.MatchAll()
75+
)
76+
.Path(i => i.Children)
77+
.InnerHits()
78+
)
79+
)
80+
.Index(indexName)
81+
);
82+
83+
var child = result.Hits.First().InnerHits.Single().Value.Documents<Child>().Single();
84+
85+
child.Should().NotBeNull();
86+
child.StartTime.Should().Be(startTime);
87+
child.EndTime.Should().Be(endTime);
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)