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

ExcludePropertyReferences #359

Merged
merged 1 commit into from
Aug 5, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/ServiceStack.Text/Common/WriteType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Reflection;
using ServiceStack.Text.Json;
using ServiceStack.Text.Reflection;
Expand Down Expand Up @@ -123,7 +124,7 @@ private static bool Init()
{
var propertyInfo = propertyInfos[i];

string propertyName, propertyNameCLSFriendly, propertyNameLowercaseUnderscore;
string propertyName, propertyNameCLSFriendly, propertyNameLowercaseUnderscore, propertyReflectedName;

if (isDataContract)
{
Expand All @@ -133,12 +134,14 @@ private static bool Init()
propertyName = dcsDataMember.Name ?? propertyInfo.Name;
propertyNameCLSFriendly = dcsDataMember.Name ?? propertyName.ToCamelCase();
propertyNameLowercaseUnderscore = dcsDataMember.Name ?? propertyName.ToLowercaseUnderscore();
propertyReflectedName = dcsDataMember.Name ?? propertyInfo.ReflectedType.Name;
}
else
{
propertyName = propertyInfo.Name;
propertyNameCLSFriendly = propertyName.ToCamelCase();
propertyNameLowercaseUnderscore = propertyName.ToLowercaseUnderscore();
propertyReflectedName = propertyInfo.ReflectedType.Name;
}

var propertyType = propertyInfo.PropertyType;
Expand All @@ -149,6 +152,7 @@ private static bool Init()
PropertyWriters[i] = new TypePropertyWriter
(
propertyName,
propertyReflectedName,
propertyNameCLSFriendly,
propertyNameLowercaseUnderscore,
propertyInfo.GetValueGetter<T>(),
Expand All @@ -164,6 +168,7 @@ private static bool Init()
string propertyName = fieldInfo.Name;
string propertyNameCLSFriendly = propertyName.ToCamelCase();
string propertyNameLowercaseUnderscore = propertyName.ToLowercaseUnderscore();
string propertyReflectedName = fieldInfo.ReflectedType.Name;

var propertyType = fieldInfo.FieldType;
var suppressDefaultValue = propertyType.IsValueType() && JsConfig.HasSerializeFn.Contains(propertyType)
Expand All @@ -173,6 +178,7 @@ private static bool Init()
PropertyWriters[i + propertyNamesLength] = new TypePropertyWriter
(
propertyName,
propertyReflectedName,
propertyNameCLSFriendly,
propertyNameLowercaseUnderscore,
fieldInfo.GetValueGetter<T>(),
Expand All @@ -198,16 +204,20 @@ internal string PropertyName
}
}
internal readonly string propertyName;
internal readonly string propertyReflectedName;
internal readonly string propertyCombinedNameUpper;
internal readonly string propertyNameCLSFriendly;
internal readonly string propertyNameLowercaseUnderscore;
internal readonly Func<T, object> GetterFn;
internal readonly WriteObjectDelegate WriteFn;
internal readonly object DefaultValue;

public TypePropertyWriter(string propertyName, string propertyNameCLSFriendly, string propertyNameLowercaseUnderscore,
public TypePropertyWriter(string propertyName, string propertyReflectedName, string propertyNameCLSFriendly, string propertyNameLowercaseUnderscore,
Func<T, object> getterFn, WriteObjectDelegate writeFn, object defaultValue)
{
this.propertyName = propertyName;
this.propertyReflectedName = propertyReflectedName;
this.propertyCombinedNameUpper = propertyReflectedName.ToUpper() + "." + propertyName.ToUpper();
this.propertyNameCLSFriendly = propertyNameCLSFriendly;
this.propertyNameLowercaseUnderscore = propertyNameLowercaseUnderscore;
this.GetterFn = getterFn;
Expand Down Expand Up @@ -274,6 +284,8 @@ public static void WriteProperties(TextWriter writer, object value)
if (PropertyWriters != null)
{
var len = PropertyWriters.Length;
var exclude = JsConfig.ExcludePropertyReferences ?? new string[0];
exclude = Array.ConvertAll(exclude, x => x.ToUpper());
for (int index = 0; index < len; index++)
{
var propertyWriter = PropertyWriters[index];
Expand All @@ -285,6 +297,8 @@ public static void WriteProperties(TextWriter writer, object value)
|| (propertyWriter.DefaultValue != null && propertyWriter.DefaultValue.Equals(propertyValue)))
&& !Serializer.IncludeNullValues) continue;

if (exclude.Any() && exclude.Contains(propertyWriter.propertyCombinedNameUpper)) continue;

if (i++ > 0)
writer.Write(JsWriter.ItemSeperator);

Expand Down
15 changes: 14 additions & 1 deletion src/ServiceStack.Text/JsConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public static JsConfigScope BeginScope()
bool? escapeUnicode = null,
bool? includePublicFields = null,
int? maxDepth = null,
EmptyCtorFactoryDelegate modelFactory = null)
EmptyCtorFactoryDelegate modelFactory = null,
string[] excludePropertyReferences = null)
{
return new JsConfigScope {
ConvertObjectTypesIntoStringDictionary = convertObjectTypesIntoStringDictionary ?? sConvertObjectTypesIntoStringDictionary,
Expand All @@ -75,6 +76,7 @@ public static JsConfigScope BeginScope()
IncludePublicFields = includePublicFields ?? sIncludePublicFields,
MaxDepth = maxDepth ?? sMaxDepth,
ModelFactory = modelFactory ?? ModelFactory,
ExcludePropertyReferences = excludePropertyReferences ?? sExcludePropertyReferences
};
}

Expand Down Expand Up @@ -523,6 +525,16 @@ public static EmptyCtorFactoryDelegate ModelFactory
}
}

private static string[] sExcludePropertyReferences;
public static string[] ExcludePropertyReferences {
get {
return (JsConfigScope.Current != null ? JsConfigScope.Current.ExcludePropertyReferences : null)
?? sExcludePropertyReferences;
}
set {
if (sExcludePropertyReferences != null) sExcludePropertyReferences = value;
}
}

public static void Reset()
{
Expand Down Expand Up @@ -556,6 +568,7 @@ public static void Reset()
HasSerializeFn = new HashSet<Type>();
TreatValueAsRefTypes = new HashSet<Type> { typeof(KeyValuePair<,>) };
PropertyConvention = JsonPropertyConvention.ExactMatch;
sExcludePropertyReferences = null;
}

public static void Reset(Type cachesForType)
Expand Down
1 change: 1 addition & 0 deletions src/ServiceStack.Text/JsConfigScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@ public void Dispose()
public bool? IncludePublicFields { get; set; }
public int? MaxDepth { get; set; }
public EmptyCtorFactoryDelegate ModelFactory { get; set; }
public string[] ExcludePropertyReferences { get; set; }
}
}
89 changes: 89 additions & 0 deletions tests/ServiceStack.Text.Tests/AdhocModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,95 @@ public void Can_exclude_properties()
Assert.That(dto.ToJsv(), Is.EqualTo("{Key:Value}"));
}

[Test]
public void Can_exclude_properties_scoped() {
var dto = new Exclude {Id = 1, Key = "Value"};
using (var config = JsConfig.BeginScope()) {
config.ExcludePropertyReferences = new[] {"Exclude.Id"};
Assert.That(dto.ToJson(), Is.EqualTo("{\"Key\":\"Value\"}"));
Assert.That(dto.ToJsv(), Is.EqualTo("{Key:Value}"));
}
}

public class IncludeExclude {
public int Id { get; set; }
public string Name { get; set; }
public Exclude Obj { get; set; }
}

[Test]
public void Can_include_nested_only() {
var dto = new IncludeExclude {
Id = 1234,
Name = "TEST",
Obj = new Exclude {
Id = 1,
Key = "Value"
}
};

using (var config = JsConfig.BeginScope()) {
config.ExcludePropertyReferences = new[] { "Exclude.Id", "IncludeExclude.Id", "IncludeExclude.Name" };
Assert.That(dto.ToJson(), Is.EqualTo("{\"Obj\":{\"Key\":\"Value\"}}"));
Assert.That(dto.ToJsv(), Is.EqualTo("{Obj:{Key:Value}}"));
}
Assert.That(JsConfig.ExcludePropertyReferences, Is.EqualTo(null));

}

[Test]
public void Exclude_all_nested()
{
var dto = new IncludeExclude
{
Id = 1234,
Name = "TEST",
Obj = new Exclude
{
Id = 1,
Key = "Value"
}
};

using (var config = JsConfig.BeginScope())
{
config.ExcludePropertyReferences = new[] { "Exclude.Id", "Exclude.Key" };
Assert.AreEqual(2, config.ExcludePropertyReferences.Length);

var actual = dto.ToJson();
Assert.That(actual, Is.EqualTo("{\"Id\":1234,\"Name\":\"TEST\",\"Obj\":{}}"));
Assert.That(dto.ToJsv(), Is.EqualTo("{Id:1234,Name:TEST,Obj:{}}"));
}
}

public class ExcludeList {
public int Id { get; set; }
public List<Exclude> Excludes { get; set; }
}

[Test]
public void Exclude_List_Scope() {
var dto = new ExcludeList {
Id = 1234,
Excludes = new List<Exclude>() {
new Exclude {
Id = 2345,
Key = "Value"
},
new Exclude {
Id = 3456,
Key = "Value"
}
}
};
using (var config = JsConfig.BeginScope())
{
config.ExcludePropertyReferences = new[] { "ExcludeList.Id", "Exclude.Id" };
Assert.That(dto.ToJson(), Is.EqualTo("{\"Excludes\":[{\"Key\":\"Value\"},{\"Key\":\"Value\"}]}"));
Assert.That(dto.ToJsv(), Is.EqualTo("{Excludes:[{Key:Value},{Key:Value}]}"));
}
}

public class HasIndex
{
public int Id { get; set; }
Expand Down