Serializing Private Member Data

Serializing private member data

You could use DataContractSerializer (but note you can't use xml attributes - only xml elements):

using System;
using System.Runtime.Serialization;
using System.Xml;
[DataContract]
class MyObject {
public MyObject(Guid id) { this.id = id; }
[DataMember(Name="Id")]
private Guid id;
public Guid Id { get {return id;}}
}
static class Program {
static void Main() {
var ser = new DataContractSerializer(typeof(MyObject));
var obj = new MyObject(Guid.NewGuid());
using(XmlWriter xw = XmlWriter.Create(Console.Out)) {
ser.WriteObject(xw, obj);
}
}
}

Alternatively, you can implement IXmlSerializable and do everything yourself - but this works with XmlSerializer, at least.

C# serialize private class member

Going on the assumption of a typo, I'd like to redirect you to this SO article where the solution is to use a DataContractSerializer instead.

Get .NET Core JsonSerializer to serialize private members

It seems System.Text.Json does not support private property serialization.

https://docs.microsoft.com/tr-tr/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to#internal-and-private-property-setters-and-getters

But as the Microsoft's document says, you can do it with custom converters.

https://www.thinktecture.com/en/asp-net/aspnet-core-3-0-custom-jsonconverter-for-the-new-system_text_json/

Code snippet for serialization;

  public class Category
{
public Category(List<string> names)
{
this.Names1 = names;
}

private List<string> Names1 { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
}


public class CategoryJsonConverter : JsonConverter<Category>
{
public override Category Read(ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
var name = reader.GetString();

var source = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(name);

var category = new Category(null);

var categoryType = category.GetType();
var categoryProps = categoryType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

foreach (var s in source.Keys)
{
var categoryProp = categoryProps.FirstOrDefault(x => x.Name == s);

if (categoryProp != null)
{
var value = JsonSerializer.Deserialize(source[s].GetRawText(), categoryProp.PropertyType);

categoryType.InvokeMember(categoryProp.Name,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance,
null,
category,
new object[] { value });
}
}

return category;
}

public override void Write(Utf8JsonWriter writer,
Category value,
JsonSerializerOptions options)
{
var props = value.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.ToDictionary(x => x.Name, x => x.GetValue(value));

var ser = JsonSerializer.Serialize(props);

writer.WriteStringValue(ser);
}
}

static void Main(string[] args)
{
Category category = new Category(new List<string>() { "1" });
category.Name2 = "2";
category.Name3 = "3";

var opt = new JsonSerializerOptions
{
Converters = { new CategoryJsonConverter() },
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

var json = JsonSerializer.Serialize(category, opt);

var obj = JsonSerializer.Deserialize<Category>(json, opt);

Console.WriteLine(json);
Console.ReadKey();
}

Result;

"{\"Names1\":[\"1\"],\"Name2\":\"2\",\"Name3\":\"3\"}"

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


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

Serialization happens using reflection so we can change your question:

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

So here is answer

Serializing readonly member data

Serializing will only serialize public fields as well as public properties that you can both get and set. The reason for the latter is that if you cannot set it, then when you go to deserialize it, how do you set the property?

Since the class isn't sealed, you could inherit from it, define a setter, but have it do nothing, i.e.

public string Name
{
get {return _name;}
set { }
}

The thing to look out for is when you deserialize to that class, the data will be lost.

HTH,
Brian

Serializing private variables in java

The Serialization API doesn't worry about private variables. Its purpose is to convert your object to a binary representation in a file or some other kind of storage that can be reconstructed later.

Here is Java's serialization algorithm explained.



Related Topics



Leave a reply



Submit