-3

I need to (de)serialize objects which reference 3rd party API objects which arent serializable. However I dont need their content to be serialized. I just want to serialize Id of these objects and then retrieve them on deserailization.

Short example:

class MyClass
{
    public int Id;
    public I3rdParyObject Data;
}

I want a custom logic to be called on (de)serializing Data. I would write to text "Data": "abc" on serialization and retrieve it on deserialization like: deserializedObject.Data = DataManager.GetDataById("abc")

dbc
  • 104,963
  • 20
  • 228
  • 340
Boppity Bop
  • 9,613
  • 13
  • 72
  • 151
  • How do you extract `"abc"` from `I3rdParyObject`? Is there some `public string Id { get; }` property? Also is `I3rdParyObject` an interface type? – dbc Jun 10 '23 at 15:39

1 Answers1

0

Assuming that the text "abc" can be extracted from I3rdParyObject itself, e.g. via some property:

public interface I3rdParyObject
{
    public string Id { get; }
    // Remainder not shown in your question
}

You can write a custom JsonConverter<I3rdParyObject> for I3rdParyObject like so:

public class I3rdParyObjectConverter : JsonConverter<I3rdParyObject>
{
    public override void Write(Utf8JsonWriter writer, I3rdParyObject value, JsonSerializerOptions options) =>
        writer.WriteStringValue(value.Id);
    
    public override I3rdParyObject Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 
        DataManager.GetDataById(reader.GetString()!);
}

Or if the Id cannot be obtained directly from I3rdParyObject but can be returned by DataManager using some method like:

public static class DataManager
{
    public static string GetDataId(I3rdParyObject obj) => /* Logic to get the Id */
}

Then WriteJson() could be written as follows:

    public override void Write(Utf8JsonWriter writer, I3rdParyObject value, JsonSerializerOptions options) =>
        writer.WriteStringValue(DataManager.GetDataId(value));

Then add the converter to JsonSerializerOptions during serialization like so when serializing or deserializing:

var options = new JsonSerializerOptions
{
    Converters = { new I3rdParyObjectConverter() },
    // Other options as required
    IncludeFields = true,  // You must set this if MyClass.Id and MyClass.Data are really fields not properties.
};

var json = JsonSerializer.Serialize(myClass, options);
var myClass2 = JsonSerializer.Deserialize<MyClass>(json, options);

Notes:

Demo fiddle here.

dbc
  • 104,963
  • 20
  • 228
  • 340