Home > Enterprise >  How to serialize and deserialize an object as a string?
How to serialize and deserialize an object as a string?

Time:11-16

I would like to serialize (and deserialize) an C# object to a json string. Normally when objects are serialized, objects are enclosed in a pair of {} in the generated json. But here I am interested in object to be serialized to only a string.

I am interested in doing this to encapsulate logic about how ItemNumbers should be formatted. But I am not interested expose the fact that I am using a class for the ItemNumber instead of an ordinary string.

Here is an example of what I am looking for. The class ItemNumber is contained in the class Item.

public class ItemNumber
{
    private string _value;

    public ItemNumber(string num)
    {
        _value = num;
    }
}

public class Item
{
    public ItemNumber ItemNumber { get; set; }
}

public void Main()
{
    var itemNumber = new ItemNumber("ABC-1234");
    var item = new Item
    {
        ItemNumber = itemNumber,
    };

    var json = System.Text.Json.JsonSerializer.Serialize(item);
}

I would like for an Item to be serialized to json looking like this:

{
    "itemNumber": "ABC-1234" // <- Notice, not an object. Just a string
}

I understand that I probably have to implement custom serializer, but the guide have found seems to assume that a C# object should always be serialized to a json object.

How do implement the serialization logic I am looking for?

CodePudding user response:

The answer for how to do this is explained in the System.Text.Json documentation. Implement a custom converter and use that during serialization.

Note: it is not possible to extract the value from ItemNumber in your example, I implemented the ToString method.

public class ItemNumber
{
    private string _value;

    public ItemNumber(string num)
    {
        _value = num;
    }

    public override string ToString()
    {
        return _value;
    }
}

public class Item
{
    // rename output property
    [JsonPropertyName("itemNumber")]
    // use custom converter
    [JsonConverter(typeof(ItemNumberJsonConverter))]
    public ItemNumber ItemNumber { get; set; }
}

public class ItemNumberJsonConverter : JsonConverter<ItemNumber>
{
    public override ItemNumber Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options) =>
            new ItemNumber(reader.GetString()!);

    public override void Write(
        Utf8JsonWriter writer,
        ItemNumber val,
        JsonSerializerOptions options) => writer.WriteStringValue(val.ToString());
}

internal class Program
{
    static void Main(string[] args)
    {
        var itemNumber = new ItemNumber("ABC-1234");
        var item = new Item
        {
            ItemNumber = itemNumber,
        };

        var serializeOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
        };

        var json = System.Text.Json.JsonSerializer.Serialize(item, serializeOptions);

        Console.WriteLine(json);
    }
}

console output

{
  "itemNumber": "ABC-1234"
}

CodePudding user response:

you will not need any custom serialiazers, if you add some attributes to your classes

public class Item
{
    [System.Text.Json.Serialization.JsonIgnore]
    public ItemNumber ItemNumber { get; set; }

    [System.Text.Json.Serialization.JsonPropertyName("itemNumber")]
    public string _itemNumberValue
    {
        get { return ItemNumber==null? null: ItemNumber.ToString(); }
        set {ItemNumber = new ItemNumber(value);}
    }

    public Item(string itemNumber)
    {
        ItemNumber = new ItemNumber(itemNumber);
    }
    public Item() { }
}

CodePudding user response:

I dont know why you wont just do this???
Add ? if you want to allow the values of the object to be nullable.

public class ItemNumber
{
    public string? Number { get; set; }

    public ItemNumber(string itemNumber)
    {
        this.Number = itemNumber;
    }
}
public class Item
{
    //Can be any data type / object
    public int? ItemNumber { get; set; }
    public List<int>? ItemNumbers { get; set; }
    public ItemNumber? Number { get; set; }
}

and then...

//Where ever you're populating the object
var itemNumbers = new Item
{
    ItemNumber = 1,
    ItemNumbers = new List<int> { 1, 2, 3, 4 },
    Number = new ItemNumber("ABC-1234")
};

//Write this output to a new file or and existing one to update it.
var output = JsonConvert.SerializeObject(itemNumbers);
/* Output
 * {
 *     "ItemNumber": 1,
 *     "ItemNumbers": [1,2,3,4],
 *     "Number": {"Number":"ABC-1234"}
 * }
 */

Edit: Would highly recommend using Newtonsoft.

  • Related