kilgoretrout
kilgoretrout

Reputation: 3657

Why does the C# DataMember attribute allow serialization of private fields and properties?

If you add the DataMember attribute to any field or property, including private one's, they will still get serialized. Microsoft notes this explicitly in their docs:

"You can apply the DataMemberAttribute to private fields or properties. Be aware that the data returned by the member (even if it's private) will be serialized and deserialized, and thus can be viewed or intercepted by a malicious user or process."

For example:

public class MyClass
{
    [DataMember(Name = "pushed_at")] 
    private string JsonDate { get; set; } //PRIVATE!

    [IgnoreDataMember]
    public DateTime PushedAt
    {
        get { return JsonDate; }
    }
}

var serializer = new DataContractJsonSerializer(typeof(List<MyClass>));
var streamTask = client.GetStreamAsync("https://api.mysite.com/hit");
var classes = serializer.ReadObject(await streamTask) as List<MyClass>;

foreach (var myClass in classes)
{
    Console.WriteLine(myClass.JsonDate); //Error because private
    Console.WriteLine(myClass.PushedAt); //Ok and shows serialized data
}

Why does this make sense? Isn't the principle of self-encapsulation much more fundamental than serialization? Is the DataMember attribute really giving access to a private property outside the class or am I missing something under the hood?

The same thing happens if you make JsonDate public and give it a private setter.

Upvotes: 2

Views: 2710

Answers (2)

Jack Sparrow
Jack Sparrow

Reputation: 607

Isn't the principle of self-encapsulation much more fundamental than serialization?

Serialization happens via reflection so we can change your question:

Isn't the principle of self-encapsulation much more fundamental than reflection?

So here is the answer

Upvotes: 7

CodeCaster
CodeCaster

Reputation: 151594

Isn't the principle of self-encapsulation much more fundamental than serialization?

No. "Pure" programming principles are nice in principle, but sometimes you just have to get things done.

If that includes deserializing into a private member, for whatever reason, the .NET design team apparently decided they're not going to stop you from doing so, even if that would mean there's more clean code out there.

They made this choice deliberately, given it's documented as you claim.

Upvotes: 2

Related Questions