Skip to content

Commit 7448fa8

Browse files
authored
Treat JToken properties as primitive attributes for serialization (#123)
1 parent dfef278 commit 7448fa8

5 files changed

Lines changed: 144 additions & 89 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -1,89 +1,110 @@
11
{
2-
"data": [
3-
{
4-
"type": "samples",
5-
"id": "1",
6-
"attributes": {
7-
"boolean-field": false,
8-
"byte-field": 0,
9-
"complex-attribute-field": null,
10-
"date-time-field": "0001-01-01T00:00:00",
11-
"date-time-offset-field": "0001-01-01T00:00:00.0000000+00:00",
12-
"decimal-field": "0",
13-
"double-field": 0.0,
14-
"enum-field": 0,
15-
"guid-field": "00000000-0000-0000-0000-000000000000",
16-
"int16-field": 0,
17-
"int32-field": 0,
18-
"int64-field": 0,
19-
"nullable-boolean-field": false,
20-
"nullable-byte-field": null,
21-
"nullable-date-time-field": null,
22-
"nullable-date-time-offset-field": null,
23-
"nullable-decimal-field": null,
24-
"nullable-double-field": null,
25-
"nullable-enum-field": null,
26-
"nullable-guid-field": null,
27-
"nullable-int16-field": null,
28-
"nullable-int32-field": null,
29-
"nullable-int64-field": null,
30-
"nullable-sbyte-field": null,
31-
"nullable-single-field": null,
32-
"nullable-uint16-field": null,
33-
"nullable-uint32-field": null,
34-
"nullable-uint64-field": null,
35-
"sbyte-field": 0,
36-
"single-field": 0.0,
37-
"string-field": null,
38-
"uint16-field": 0,
39-
"uint32-field": 0,
40-
"uint64-field": 0
41-
}
2+
"data": [
3+
{
4+
"type": "samples",
5+
"id": "1",
6+
"attributes": {
7+
"boolean-field": false,
8+
"byte-field": 0,
9+
"complex-attribute-field": null,
10+
"date-time-field": "0001-01-01T00:00:00",
11+
"date-time-offset-field": "0001-01-01T00:00:00.0000000+00:00",
12+
"decimal-field": "0",
13+
"double-field": 0.0,
14+
"enum-field": 0,
15+
"guid-field": "00000000-0000-0000-0000-000000000000",
16+
"int16-field": 0,
17+
"int32-field": 0,
18+
"int64-field": 0,
19+
"j-token-array-field": null,
20+
"j-token-object-field": null,
21+
"j-token-string-field": null,
22+
"nullable-boolean-field": false,
23+
"nullable-byte-field": null,
24+
"nullable-date-time-field": null,
25+
"nullable-date-time-offset-field": null,
26+
"nullable-decimal-field": null,
27+
"nullable-double-field": null,
28+
"nullable-enum-field": null,
29+
"nullable-guid-field": null,
30+
"nullable-int16-field": null,
31+
"nullable-int32-field": null,
32+
"nullable-int64-field": null,
33+
"nullable-sbyte-field": null,
34+
"nullable-single-field": null,
35+
"nullable-uint16-field": null,
36+
"nullable-uint32-field": null,
37+
"nullable-uint64-field": null,
38+
"sbyte-field": 0,
39+
"single-field": 0.0,
40+
"string-field": null,
41+
"uint16-field": 0,
42+
"uint32-field": 0,
43+
"uint64-field": 0
44+
}
45+
},
46+
{
47+
"type": "samples",
48+
"id": "2",
49+
"attributes": {
50+
"boolean-field": true,
51+
"byte-field": 253,
52+
"complex-attribute-field": {
53+
"foo": {
54+
"baz": [ 11 ]
55+
},
56+
"bar": 5
4257
},
43-
{
44-
"type": "samples",
45-
"id": "2",
46-
"attributes": {
47-
"boolean-field": true,
48-
"byte-field": 253,
49-
"complex-attribute-field": {
50-
"foo": {
51-
"baz": [ 11 ]
52-
},
53-
"bar": 5
54-
},
55-
"date-time-field": "1776-07-04T00:00:00",
56-
"date-time-offset-field": "1776-07-04T00:00:00.0000000-05:00",
57-
"decimal-field": "1056789.123",
58-
"double-field": 1056789.123,
59-
"enum-field": 1,
60-
"guid-field": "6566f9b4-5245-40de-890d-98b40a4ad656",
61-
"int16-field": 32000,
62-
"int32-field": 2000000000,
63-
"int64-field": 9223372036854775807,
64-
"nullable-boolean-field": true,
65-
"nullable-byte-field": 253,
66-
"nullable-date-time-field": "1776-07-04T00:00:00",
67-
"nullable-date-time-offset-field": "1776-07-04T00:00:00.0000000-05:00",
68-
"nullable-decimal-field": "1056789.123",
69-
"nullable-double-field": 1056789.123,
70-
"nullable-enum-field": 2,
71-
"nullable-guid-field": "3d1fb81e-43ee-4d04-af91-c8a326341293",
72-
"nullable-int16-field": 32000,
73-
"nullable-int32-field": 2000000000,
74-
"nullable-int64-field": 9223372036854775807,
75-
"nullable-sbyte-field": 123,
76-
"nullable-single-field": 1056789.13,
77-
"nullable-uint16-field": 64000,
78-
"nullable-uint32-field": 3000000000,
79-
"nullable-uint64-field": 9223372036854775808,
80-
"sbyte-field": 123,
81-
"single-field": 1056789.13,
82-
"string-field": "Some string 156",
83-
"uint16-field": 64000,
84-
"uint32-field": 3000000000,
85-
"uint64-field": 9223372036854775808
86-
}
87-
}
88-
]
58+
"date-time-field": "1776-07-04T00:00:00",
59+
"date-time-offset-field": "1776-07-04T00:00:00.0000000-05:00",
60+
"decimal-field": "1056789.123",
61+
"double-field": 1056789.123,
62+
"enum-field": 1,
63+
"guid-field": "6566f9b4-5245-40de-890d-98b40a4ad656",
64+
"int16-field": 32000,
65+
"int32-field": 2000000000,
66+
"int64-field": 9223372036854775807,
67+
"j-token-array-field": [
68+
{
69+
"my-field1": "George Washington",
70+
"overridden-field2": null,
71+
"MyField3": 216
72+
},
73+
{
74+
"my-field1": "Thomas Jefferson",
75+
"overridden-field2": false,
76+
"MyField3": 631
77+
}
78+
],
79+
"j-token-object-field": {
80+
"my-field1": "Abraham Lincoln",
81+
"overridden-field2": true,
82+
"MyField3": 439
83+
},
84+
"j-token-string-field": "Andrew Jackson",
85+
"nullable-boolean-field": true,
86+
"nullable-byte-field": 253,
87+
"nullable-date-time-field": "1776-07-04T00:00:00",
88+
"nullable-date-time-offset-field": "1776-07-04T00:00:00.0000000-05:00",
89+
"nullable-decimal-field": "1056789.123",
90+
"nullable-double-field": 1056789.123,
91+
"nullable-enum-field": 2,
92+
"nullable-guid-field": "3d1fb81e-43ee-4d04-af91-c8a326341293",
93+
"nullable-int16-field": 32000,
94+
"nullable-int32-field": 2000000000,
95+
"nullable-int64-field": 9223372036854775807,
96+
"nullable-sbyte-field": 123,
97+
"nullable-single-field": 1056789.13,
98+
"nullable-uint16-field": 64000,
99+
"nullable-uint32-field": 3000000000,
100+
"nullable-uint64-field": 9223372036854775808,
101+
"sbyte-field": 123,
102+
"single-field": 1056789.13,
103+
"string-field": "Some string 156",
104+
"uint16-field": 64000,
105+
"uint32-field": 3000000000,
106+
"uint64-field": 9223372036854775808
107+
}
108+
}
109+
]
89110
}

JSONAPI.AcceptanceTests.EntityFrameworkTestWebApp/Controllers/SamplesController.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Web.Http;
33
using JSONAPI.AcceptanceTests.EntityFrameworkTestWebApp.Models;
4+
using Newtonsoft.Json;
5+
using Newtonsoft.Json.Linq;
46

57
namespace JSONAPI.AcceptanceTests.EntityFrameworkTestWebApp.Controllers
68
{
@@ -44,7 +46,10 @@ public IHttpActionResult GetSamples()
4446
StringField = null,
4547
EnumField = default(SampleEnum),
4648
NullableEnumField = null,
47-
ComplexAttributeField = null
49+
ComplexAttributeField = null,
50+
JTokenStringField = null,
51+
JTokenObjectField = null,
52+
JTokenArrayField = null
4853
};
4954
var s2 = new Sample
5055
{
@@ -82,10 +87,27 @@ public IHttpActionResult GetSamples()
8287
StringField = "Some string 156",
8388
EnumField = SampleEnum.Value1,
8489
NullableEnumField = SampleEnum.Value2,
85-
ComplexAttributeField = "{\"foo\": { \"baz\": [11] }, \"bar\": 5}"
90+
ComplexAttributeField = "{\"foo\": { \"baz\": [11] }, \"bar\": 5}",
91+
JTokenStringField = "Andrew Jackson",
92+
JTokenObjectField = JToken.FromObject(new SomeSerializableClass { MyField1 = "Abraham Lincoln", MyField2 = true, MyField3 = 439 }),
93+
JTokenArrayField = new JArray(
94+
JToken.FromObject(new SomeSerializableClass { MyField1 = "George Washington", MyField2 = null, MyField3 = 216 }),
95+
JToken.FromObject(new SomeSerializableClass { MyField1 = "Thomas Jefferson", MyField2 = false, MyField3 = 631 }))
8696
};
8797

8898
return Ok(new[] { s1, s2 });
8999
}
100+
101+
[Serializable]
102+
public class SomeSerializableClass
103+
{
104+
[JsonProperty("my-field1")]
105+
public string MyField1 { get; set; }
106+
107+
[JsonProperty("overridden-field2")]
108+
public bool? MyField2 { get; set; }
109+
110+
public int MyField3 { get; set; }
111+
}
90112
}
91113
}

JSONAPI.AcceptanceTests.EntityFrameworkTestWebApp/Models/Sample.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using JSONAPI.Attributes;
3+
using Newtonsoft.Json.Linq;
34

45
namespace JSONAPI.AcceptanceTests.EntityFrameworkTestWebApp.Models
56
{
@@ -48,5 +49,11 @@ public class Sample
4849

4950
[SerializeAsComplex]
5051
public string ComplexAttributeField { get; set; }
52+
53+
public JToken JTokenStringField { get; set; }
54+
55+
public JToken JTokenObjectField { get; set; }
56+
57+
public JToken JTokenArrayField { get; set; }
5158
}
5259
}

JSONAPI.Tests/Extensions/TypeExtensionsTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using JSONAPI.Extensions;
33
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Newtonsoft.Json.Linq;
45

56
namespace JSONAPI.Tests.Extensions
67
{
@@ -46,6 +47,9 @@ public void CanWriteAsJsonApiAttributeTest()
4647
Assert.IsTrue(typeof(String).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for String!");
4748
Assert.IsTrue(typeof(TestEnum).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for enum!");
4849
Assert.IsTrue(typeof(TestEnum?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable enum!");
50+
Assert.IsTrue(typeof(JToken).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for JToken!");
51+
Assert.IsTrue(typeof(JObject).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for JObject!");
52+
Assert.IsTrue(typeof(JArray).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Jarray!");
4953
Assert.IsFalse(typeof(Object).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Object!");
5054
}
5155

JSONAPI/Extensions/TypeExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3-
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Linq;
44

55
namespace JSONAPI.Extensions
66
{
@@ -17,6 +17,7 @@ public static bool CanWriteAsJsonApiAttribute(this Type objectType)
1717
|| typeof (DateTime).IsAssignableFrom(objectType)
1818
|| typeof (DateTimeOffset).IsAssignableFrom(objectType)
1919
|| typeof (String).IsAssignableFrom(objectType)
20+
|| typeof (JToken).IsAssignableFrom(objectType)
2021
|| objectType.IsEnum;
2122
}
2223

0 commit comments

Comments
 (0)