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

Commit bb24c3e

Browse files
committed
Merge pull request #359 from nhalm/ExcludePropertyReferences
ExcludePropertyReferences
2 parents e123a09 + a0d2c27 commit bb24c3e

File tree

4 files changed

+120
-3
lines changed

4 files changed

+120
-3
lines changed

src/ServiceStack.Text/Common/WriteType.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using System;
1414
using System.Collections;
1515
using System.IO;
16+
using System.Linq;
1617
using System.Reflection;
1718
using ServiceStack.Text.Json;
1819
using ServiceStack.Text.Reflection;
@@ -123,7 +124,7 @@ private static bool Init()
123124
{
124125
var propertyInfo = propertyInfos[i];
125126

126-
string propertyName, propertyNameCLSFriendly, propertyNameLowercaseUnderscore;
127+
string propertyName, propertyNameCLSFriendly, propertyNameLowercaseUnderscore, propertyReflectedName;
127128

128129
if (isDataContract)
129130
{
@@ -133,12 +134,14 @@ private static bool Init()
133134
propertyName = dcsDataMember.Name ?? propertyInfo.Name;
134135
propertyNameCLSFriendly = dcsDataMember.Name ?? propertyName.ToCamelCase();
135136
propertyNameLowercaseUnderscore = dcsDataMember.Name ?? propertyName.ToLowercaseUnderscore();
137+
propertyReflectedName = dcsDataMember.Name ?? propertyInfo.ReflectedType.Name;
136138
}
137139
else
138140
{
139141
propertyName = propertyInfo.Name;
140142
propertyNameCLSFriendly = propertyName.ToCamelCase();
141143
propertyNameLowercaseUnderscore = propertyName.ToLowercaseUnderscore();
144+
propertyReflectedName = propertyInfo.ReflectedType.Name;
142145
}
143146

144147
var propertyType = propertyInfo.PropertyType;
@@ -149,6 +152,7 @@ private static bool Init()
149152
PropertyWriters[i] = new TypePropertyWriter
150153
(
151154
propertyName,
155+
propertyReflectedName,
152156
propertyNameCLSFriendly,
153157
propertyNameLowercaseUnderscore,
154158
propertyInfo.GetValueGetter<T>(),
@@ -164,6 +168,7 @@ private static bool Init()
164168
string propertyName = fieldInfo.Name;
165169
string propertyNameCLSFriendly = propertyName.ToCamelCase();
166170
string propertyNameLowercaseUnderscore = propertyName.ToLowercaseUnderscore();
171+
string propertyReflectedName = fieldInfo.ReflectedType.Name;
167172

168173
var propertyType = fieldInfo.FieldType;
169174
var suppressDefaultValue = propertyType.IsValueType() && JsConfig.HasSerializeFn.Contains(propertyType)
@@ -173,6 +178,7 @@ private static bool Init()
173178
PropertyWriters[i + propertyNamesLength] = new TypePropertyWriter
174179
(
175180
propertyName,
181+
propertyReflectedName,
176182
propertyNameCLSFriendly,
177183
propertyNameLowercaseUnderscore,
178184
fieldInfo.GetValueGetter<T>(),
@@ -198,16 +204,20 @@ internal string PropertyName
198204
}
199205
}
200206
internal readonly string propertyName;
207+
internal readonly string propertyReflectedName;
208+
internal readonly string propertyCombinedNameUpper;
201209
internal readonly string propertyNameCLSFriendly;
202210
internal readonly string propertyNameLowercaseUnderscore;
203211
internal readonly Func<T, object> GetterFn;
204212
internal readonly WriteObjectDelegate WriteFn;
205213
internal readonly object DefaultValue;
206214

207-
public TypePropertyWriter(string propertyName, string propertyNameCLSFriendly, string propertyNameLowercaseUnderscore,
215+
public TypePropertyWriter(string propertyName, string propertyReflectedName, string propertyNameCLSFriendly, string propertyNameLowercaseUnderscore,
208216
Func<T, object> getterFn, WriteObjectDelegate writeFn, object defaultValue)
209217
{
210218
this.propertyName = propertyName;
219+
this.propertyReflectedName = propertyReflectedName;
220+
this.propertyCombinedNameUpper = propertyReflectedName.ToUpper() + "." + propertyName.ToUpper();
211221
this.propertyNameCLSFriendly = propertyNameCLSFriendly;
212222
this.propertyNameLowercaseUnderscore = propertyNameLowercaseUnderscore;
213223
this.GetterFn = getterFn;
@@ -274,6 +284,8 @@ public static void WriteProperties(TextWriter writer, object value)
274284
if (PropertyWriters != null)
275285
{
276286
var len = PropertyWriters.Length;
287+
var exclude = JsConfig.ExcludePropertyReferences ?? new string[0];
288+
exclude = Array.ConvertAll(exclude, x => x.ToUpper());
277289
for (int index = 0; index < len; index++)
278290
{
279291
var propertyWriter = PropertyWriters[index];
@@ -285,6 +297,8 @@ public static void WriteProperties(TextWriter writer, object value)
285297
|| (propertyWriter.DefaultValue != null && propertyWriter.DefaultValue.Equals(propertyValue)))
286298
&& !Serializer.IncludeNullValues) continue;
287299

300+
if (exclude.Any() && exclude.Contains(propertyWriter.propertyCombinedNameUpper)) continue;
301+
288302
if (i++ > 0)
289303
writer.Write(JsWriter.ItemSeperator);
290304

src/ServiceStack.Text/JsConfig.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public static JsConfigScope With(
5050
bool? escapeUnicode = null,
5151
bool? includePublicFields = null,
5252
int? maxDepth = null,
53-
EmptyCtorFactoryDelegate modelFactory = null)
53+
EmptyCtorFactoryDelegate modelFactory = null,
54+
string[] excludePropertyReferences = null)
5455
{
5556
return new JsConfigScope {
5657
ConvertObjectTypesIntoStringDictionary = convertObjectTypesIntoStringDictionary ?? sConvertObjectTypesIntoStringDictionary,
@@ -75,6 +76,7 @@ public static JsConfigScope With(
7576
IncludePublicFields = includePublicFields ?? sIncludePublicFields,
7677
MaxDepth = maxDepth ?? sMaxDepth,
7778
ModelFactory = modelFactory ?? ModelFactory,
79+
ExcludePropertyReferences = excludePropertyReferences ?? sExcludePropertyReferences
7880
};
7981
}
8082

@@ -523,6 +525,16 @@ public static EmptyCtorFactoryDelegate ModelFactory
523525
}
524526
}
525527

528+
private static string[] sExcludePropertyReferences;
529+
public static string[] ExcludePropertyReferences {
530+
get {
531+
return (JsConfigScope.Current != null ? JsConfigScope.Current.ExcludePropertyReferences : null)
532+
?? sExcludePropertyReferences;
533+
}
534+
set {
535+
if (sExcludePropertyReferences != null) sExcludePropertyReferences = value;
536+
}
537+
}
526538

527539
public static void Reset()
528540
{
@@ -556,6 +568,7 @@ public static void Reset()
556568
HasSerializeFn = new HashSet<Type>();
557569
TreatValueAsRefTypes = new HashSet<Type> { typeof(KeyValuePair<,>) };
558570
PropertyConvention = JsonPropertyConvention.ExactMatch;
571+
sExcludePropertyReferences = null;
559572
}
560573

561574
public static void Reset(Type cachesForType)

src/ServiceStack.Text/JsConfigScope.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,6 @@ public void Dispose()
7979
public bool? IncludePublicFields { get; set; }
8080
public int? MaxDepth { get; set; }
8181
public EmptyCtorFactoryDelegate ModelFactory { get; set; }
82+
public string[] ExcludePropertyReferences { get; set; }
8283
}
8384
}

tests/ServiceStack.Text.Tests/AdhocModelTests.cs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,95 @@ public void Can_exclude_properties()
334334
Assert.That(dto.ToJsv(), Is.EqualTo("{Key:Value}"));
335335
}
336336

337+
[Test]
338+
public void Can_exclude_properties_scoped() {
339+
var dto = new Exclude {Id = 1, Key = "Value"};
340+
using (var config = JsConfig.BeginScope()) {
341+
config.ExcludePropertyReferences = new[] {"Exclude.Id"};
342+
Assert.That(dto.ToJson(), Is.EqualTo("{\"Key\":\"Value\"}"));
343+
Assert.That(dto.ToJsv(), Is.EqualTo("{Key:Value}"));
344+
}
345+
}
346+
347+
public class IncludeExclude {
348+
public int Id { get; set; }
349+
public string Name { get; set; }
350+
public Exclude Obj { get; set; }
351+
}
352+
353+
[Test]
354+
public void Can_include_nested_only() {
355+
var dto = new IncludeExclude {
356+
Id = 1234,
357+
Name = "TEST",
358+
Obj = new Exclude {
359+
Id = 1,
360+
Key = "Value"
361+
}
362+
};
363+
364+
using (var config = JsConfig.BeginScope()) {
365+
config.ExcludePropertyReferences = new[] { "Exclude.Id", "IncludeExclude.Id", "IncludeExclude.Name" };
366+
Assert.That(dto.ToJson(), Is.EqualTo("{\"Obj\":{\"Key\":\"Value\"}}"));
367+
Assert.That(dto.ToJsv(), Is.EqualTo("{Obj:{Key:Value}}"));
368+
}
369+
Assert.That(JsConfig.ExcludePropertyReferences, Is.EqualTo(null));
370+
371+
}
372+
373+
[Test]
374+
public void Exclude_all_nested()
375+
{
376+
var dto = new IncludeExclude
377+
{
378+
Id = 1234,
379+
Name = "TEST",
380+
Obj = new Exclude
381+
{
382+
Id = 1,
383+
Key = "Value"
384+
}
385+
};
386+
387+
using (var config = JsConfig.BeginScope())
388+
{
389+
config.ExcludePropertyReferences = new[] { "Exclude.Id", "Exclude.Key" };
390+
Assert.AreEqual(2, config.ExcludePropertyReferences.Length);
391+
392+
var actual = dto.ToJson();
393+
Assert.That(actual, Is.EqualTo("{\"Id\":1234,\"Name\":\"TEST\",\"Obj\":{}}"));
394+
Assert.That(dto.ToJsv(), Is.EqualTo("{Id:1234,Name:TEST,Obj:{}}"));
395+
}
396+
}
397+
398+
public class ExcludeList {
399+
public int Id { get; set; }
400+
public List<Exclude> Excludes { get; set; }
401+
}
402+
403+
[Test]
404+
public void Exclude_List_Scope() {
405+
var dto = new ExcludeList {
406+
Id = 1234,
407+
Excludes = new List<Exclude>() {
408+
new Exclude {
409+
Id = 2345,
410+
Key = "Value"
411+
},
412+
new Exclude {
413+
Id = 3456,
414+
Key = "Value"
415+
}
416+
}
417+
};
418+
using (var config = JsConfig.BeginScope())
419+
{
420+
config.ExcludePropertyReferences = new[] { "ExcludeList.Id", "Exclude.Id" };
421+
Assert.That(dto.ToJson(), Is.EqualTo("{\"Excludes\":[{\"Key\":\"Value\"},{\"Key\":\"Value\"}]}"));
422+
Assert.That(dto.ToJsv(), Is.EqualTo("{Excludes:[{Key:Value},{Key:Value}]}"));
423+
}
424+
}
425+
337426
public class HasIndex
338427
{
339428
public int Id { get; set; }

0 commit comments

Comments
 (0)