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

Opt in member serialization #131

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Utf8Json/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,10 @@ public class SerializationConstructorAttribute : Attribute
{

}

[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
public class InterfaceDataContractAttribute : Attribute
{

}
}
5 changes: 5 additions & 0 deletions src/Utf8Json/Internal/Emit/MetaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ public MetaType(Type type, Func<string, string> nameMutetor, bool allowPrivate)
{
var ti = type.GetTypeInfo();
var isClass = ti.IsClass || ti.IsInterface || ti.IsAbstract;
var dataContractPresent = type.GetCustomAttribute<DataContractAttribute>(true) != null ||
type.GetCustomAttribute<InterfaceDataContractAttribute>(true) != null;

this.Type = type;

var stringMembers = new Dictionary<string, MetaMember>();

{
Expand All @@ -32,6 +35,7 @@ public MetaType(Type type, Func<string, string> nameMutetor, bool allowPrivate)
if (item.GetCustomAttribute<IgnoreDataMemberAttribute>(true) != null) continue;

var dm = item.GetCustomAttribute<DataMemberAttribute>(true);
if (dataContractPresent && dm == null) continue;
var name = (dm != null && dm.Name != null) ? dm.Name : nameMutetor(item.Name);

var member = new MetaMember(item, name, allowPrivate);
Expand All @@ -51,6 +55,7 @@ public MetaType(Type type, Func<string, string> nameMutetor, bool allowPrivate)
if (item.Name.StartsWith("<")) continue; // compiler generated field(anonymous type, etc...)

var dm = item.GetCustomAttribute<DataMemberAttribute>(true);
if (dataContractPresent && dm == null) continue;
var name = (dm != null && dm.Name != null) ? dm.Name : nameMutetor(item.Name);

var member = new MetaMember(item, name, allowPrivate);
Expand Down
98 changes: 82 additions & 16 deletions tests/Utf8Json.Tests/DataContractTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ namespace Utf8Json.Tests

public class DataContractTest
{
[DataContract]
public class MyClass
{
[DataMember(Order = 0)]
public int MyProperty1 { get; set; }
[DataMember(Order = 1)]
public string MyProperty2;
}

[DataContract]
public class MyClass1
{
Expand All @@ -40,36 +31,111 @@ public class MyClass2
[DataMember]
public int MyProperty1 { get; set; }
[DataMember]
public string MyProperty2;
public string MyProperty2;
public string MyProperty3 { get; set; }
}

public class MyClass3
{
[DataMember]
public int MyProperty1 { get; set; }
public string MyProperty2 { get; set; }
[DataMember]
public string MyProperty3;
}

[InterfaceDataContract]
public interface IMyClass4
{
[DataMember]
int MyProperty1 { get; set; }

string MyProperty2 { get; set; }
}

public class MyClass4 : IMyClass4
{
public int MyProperty1 { get; set; }
[DataMember]
public string MyProperty2 { get; set; }
}

[DataContract]
public class MyOtherClass4 : IMyClass4
{
public int MyProperty1 { get; set; }
[DataMember]
public string MyProperty2 { get; set; }
}

[Fact]
public void SerializeName()
public void SerializeDataMemberName()
{
var mc = new MyClass1 { MyProperty1 = 100, MyProperty2 = "foobar" };

var bin = JsonSerializer.Serialize(mc);

Encoding.UTF8.GetString(bin).Is(@"{""mp1"":100,""mp2"":""foobar""}");

var mc2 = JsonSerializer.Deserialize<MyClass1>(bin);

mc.MyProperty1.Is(mc2.MyProperty1);
mc.MyProperty2.Is(mc2.MyProperty2);
}

[Fact]
public void Serialize()
public void SerializeOnlyDataMemberWhenDataContract()
{
var mc = new MyClass2 { MyProperty1 = 100, MyProperty2 = "foobar" };
var mc = new MyClass2 { MyProperty1 = 100, MyProperty2 = "foobar", MyProperty3 = "baz" };

var bin = JsonSerializer.Serialize(mc);
Encoding.UTF8.GetString(bin).Is(@"{""MyProperty1"":100,""MyProperty2"":""foobar""}");

var mc2 = JsonSerializer.Deserialize<MyClass2>(bin);
mc.MyProperty1.Is(mc2.MyProperty1);
mc.MyProperty2.Is(mc2.MyProperty2);
mc.MyProperty3.IsNot(mc2.MyProperty3);
mc2.MyProperty3.Is(null);
}

[Fact]
public void Serialize()
{
var mc = new MyClass3 { MyProperty1 = 100, MyProperty2 = "foobar", MyProperty3 = "baz" };

var bin = JsonSerializer.Serialize(mc);
Encoding.UTF8.GetString(bin).Is(@"{""MyProperty1"":100,""MyProperty2"":""foobar"",""MyProperty3"":""baz""}");

var mc2 = JsonSerializer.Deserialize<MyClass3>(bin);
mc.MyProperty1.Is(mc2.MyProperty1);
mc.MyProperty2.Is(mc2.MyProperty2);
mc.MyProperty3.Is(mc2.MyProperty3);
}

Encoding.UTF8.GetString(bin).Is(@"{""MyProperty1"":100,""MyProperty2"":""foobar""}");
[Fact]
public void SerializeInterfaceOnlyDataMemberWhenInterfaceDataContract()
{
IMyClass4 mc = new MyClass4 { MyProperty1 = 100, MyProperty2 = "foobar" };

var bin = JsonSerializer.Serialize(mc);
Encoding.UTF8.GetString(bin).Is(@"{""MyProperty1"":100}");

var mc2 = JsonSerializer.Deserialize<MyClass4>(bin);
mc.MyProperty1.Is(mc2.MyProperty1);
mc.MyProperty2.IsNot(mc2.MyProperty2);
mc2.MyProperty2.Is(null);
}

[Fact]
public void SerializeConcreteOnlyDataMemberWhenDataContract()
{
var mc = new MyOtherClass4 { MyProperty1 = 100, MyProperty2 = "foobar" };

var bin = JsonSerializer.Serialize(mc);
Encoding.UTF8.GetString(bin).Is(@"{""MyProperty2"":""foobar""}");

var mc2 = JsonSerializer.Deserialize<MyOtherClass4>(bin);
mc.MyProperty1.IsNot(mc2.MyProperty1);
mc2.MyProperty1.Is(0);
mc.MyProperty2.Is(mc2.MyProperty2);
}
}

Expand Down