Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 2e07461

Browse files
committed
Add support for JsConfig.IncludeNullValuesInDictionaries
1 parent c7ec154 commit 2e07461

File tree

10 files changed

+73
-9
lines changed

10 files changed

+73
-9
lines changed

src/ServiceStack.Text/Common/DeserializeListWithElements.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,14 @@ public static ICollection<T> ParseGenericList(string value, Type createListType,
143143
do
144144
{
145145
var itemValue = Serializer.EatTypeValue(value, ref i);
146-
to.Add((T)parseFn(itemValue));
146+
if (itemValue != null)
147+
{
148+
to.Add((T)parseFn(itemValue));
149+
}
150+
else
151+
{
152+
to.Add(default(T));
153+
}
147154
Serializer.EatWhitespace(value, ref i);
148155
} while (++i < value.Length);
149156
}

src/ServiceStack.Text/Common/ITypeSerializer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace ServiceStack.Text.Common
77
public interface ITypeSerializer
88
{
99
bool IncludeNullValues { get; }
10+
bool IncludeNullValuesInDictionaries { get; }
1011
string TypeAttrInObject { get; }
1112

1213
WriteObjectDelegate GetWriteFn<T>();

src/ServiceStack.Text/Common/WriteDictionary.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public static void WriteIDictionary(TextWriter writer, object oMap)
110110
var dictionaryValue = map[key];
111111

112112
var isNull = (dictionaryValue == null);
113-
if (isNull && !Serializer.IncludeNullValues) continue;
113+
if (isNull && !Serializer.IncludeNullValuesInDictionaries) continue;
114114

115115
var keyType = key.GetType();
116116
if (writeKeyFn == null || lastKeyType != keyType)
@@ -214,7 +214,7 @@ public static void WriteGenericIDictionary(
214214
foreach (var kvp in map)
215215
{
216216
var isNull = (kvp.Value == null);
217-
if (isNull && !Serializer.IncludeNullValues) continue;
217+
if (isNull && !Serializer.IncludeNullValuesInDictionaries) continue;
218218

219219
JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
220220

src/ServiceStack.Text/JsConfig.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static JsConfigScope With(
3535
ParseAsType? parsePrimitiveIntegerTypes = null,
3636
bool? excludeDefaultValues = null,
3737
bool? includeNullValues = null,
38+
bool? includeNullValuesInDictionaries = null,
3839
bool? includeDefaultEnums = null,
3940
bool? excludeTypeInfo = null,
4041
bool? includeTypeInfo = null,
@@ -70,6 +71,7 @@ public static JsConfigScope With(
7071

7172
ExcludeDefaultValues = excludeDefaultValues ?? sExcludeDefaultValues,
7273
IncludeNullValues = includeNullValues ?? sIncludeNullValues,
74+
IncludeNullValuesInDictionaries = includeNullValuesInDictionaries ?? sIncludeNullValuesInDictionaries,
7375
IncludeDefaultEnums = includeDefaultEnums ?? sIncludeDefaultEnums,
7476
ExcludeTypeInfo = excludeTypeInfo ?? sExcludeTypeInfo,
7577
IncludeTypeInfo = includeTypeInfo ?? sIncludeTypeInfo,
@@ -201,6 +203,21 @@ public static bool IncludeNullValues
201203
}
202204
}
203205

206+
private static bool? sIncludeNullValuesInDictionaries;
207+
public static bool IncludeNullValuesInDictionaries
208+
{
209+
get
210+
{
211+
return (JsConfigScope.Current != null ? JsConfigScope.Current.IncludeNullValuesInDictionaries : null)
212+
?? sIncludeNullValuesInDictionaries
213+
?? false;
214+
}
215+
set
216+
{
217+
if (!sIncludeNullValuesInDictionaries.HasValue) sIncludeNullValuesInDictionaries = value;
218+
}
219+
}
220+
204221
private static bool? sIncludeDefaultEnums;
205222
public static bool IncludeDefaultEnums
206223
{
@@ -708,6 +725,7 @@ public static void Reset()
708725
sConvertObjectTypesIntoStringDictionary = null;
709726
sExcludeDefaultValues = null;
710727
sIncludeNullValues = null;
728+
sIncludeNullValuesInDictionaries = null;
711729
sExcludeTypeInfo = null;
712730
sEmitCamelCaseNames = null;
713731
sEmitLowercaseUnderscoreNames = null;

src/ServiceStack.Text/JsConfigScope.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public void Dispose()
6060
public ParseAsType? ParsePrimitiveIntegerTypes { get; set; }
6161
public bool? ExcludeDefaultValues { get; set; }
6262
public bool? IncludeNullValues { get; set; }
63+
public bool? IncludeNullValuesInDictionaries { get; set; }
6364
public bool? IncludeDefaultEnums { get; set; }
6465
public bool? TreatEnumAsInteger { get; set; }
6566
public bool? ExcludeTypeInfo { get; set; }

src/ServiceStack.Text/Json/JsonTypeSerializer.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public bool IncludeNullValues
1919
get { return JsConfig.IncludeNullValues; }
2020
}
2121

22+
public bool IncludeNullValuesInDictionaries
23+
{
24+
get { return JsConfig.IncludeNullValuesInDictionaries; }
25+
}
26+
2227
public string TypeAttrInObject
2328
{
2429
get { return JsConfig.JsonTypeAttrInObject; }

src/ServiceStack.Text/Jsv/JsvTypeSerializer.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ public class JsvTypeSerializer
1414
{
1515
public static ITypeSerializer Instance = new JsvTypeSerializer();
1616

17-
public bool IncludeNullValues
18-
{
17+
public bool IncludeNullValues
18+
{
1919
get { return false; } //Doesn't support null values, treated as "null" string literal
20-
}
20+
}
21+
22+
public bool IncludeNullValuesInDictionaries
23+
{
24+
get { return false; } //Doesn't support null values, treated as "null" string literal
25+
}
2126

2227
public string TypeAttrInObject
2328
{

tests/ServiceStack.Text.Tests/DictionaryTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ public void Can_deserialize_mixed_dictionary_into_strongtyped_map()
414414
[Test]
415415
public void Can_serialise_null_values_from_dictionary_correctly()
416416
{
417-
JsConfig.IncludeNullValues = true;
417+
JsConfig.IncludeNullValues = false;
418+
JsConfig.IncludeNullValuesInDictionaries = true;
418419
var dictionary = new Dictionary<string, object> { { "value", null } };
419420

420421
Serialize(dictionary, includeXml: false);
@@ -429,7 +430,8 @@ public void Can_serialise_null_values_from_dictionary_correctly()
429430
[Test]
430431
public void Will_ignore_null_values_from_dictionary_correctly()
431432
{
432-
JsConfig.IncludeNullValues = false;
433+
JsConfig.IncludeNullValues = true;
434+
JsConfig.IncludeNullValuesInDictionaries = false;
433435
var dictionary = new Dictionary<string, string> { { "value", null } };
434436

435437
Serialize(dictionary, includeXml: false);

tests/ServiceStack.Text.Tests/ExpandoTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void Can_deserialize_two_level_expando()
103103
[Test]
104104
public void Can_serialise_null_values_from_expando_correctly()
105105
{
106-
JsConfig.IncludeNullValues = true;
106+
JsConfig.IncludeNullValuesInDictionaries = true;
107107
dynamic expando = new ExpandoObject();
108108
expando.value = null;
109109

tests/ServiceStack.Text.Tests/JsonTests/JsonArrayObjectTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,30 @@ public void Can_deserialize_empty_array_with_whitespace()
135135
var result = data.FromJson<Test[]>();
136136
Assert.That(result.Length, Is.EqualTo(0));
137137
}
138+
139+
public class MyClass
140+
{
141+
public string Item { get; set; }
142+
}
143+
144+
[Test]
145+
public void Can_parse_array_with_null_objects_starting_with_not_null_item()
146+
{
147+
var compactJson = @"{""items"":[{""Item"":""myitem""},null]}";
148+
var json = JsonObject.Parse(compactJson);
149+
var items = json.ArrayObjects("items");
150+
Assert.NotNull(items[0]);
151+
Assert.Null(items[1]);
152+
}
153+
154+
[Test]
155+
public void Can_parse_array_with_null_objects_starting_with_null_item()
156+
{
157+
var compactJson = @"{""items"":[null,{""Item"":""myitem""}]}";
158+
var json = JsonObject.Parse(compactJson);
159+
var items = json.ArrayObjects("items");
160+
Assert.Null(items[0]);
161+
Assert.NotNull(items[1]);
162+
}
138163
}
139164
}

0 commit comments

Comments
 (0)