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")
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:
In your question, you state that MyClass.Id
and MyClass.Data
are fields. By default, System.Text.Json does not serialize fields. If these members are really fields and not properties, you must enable serialization of fields, e.g. by setting JsonSerializerOptions.IncludeFields = true
.
For more see How to serialize and deserialize (marshal and unmarshal) JSON in .NET: Include fields.
Demo fiddle here.