nen
nen

Reputation: 767

Add a root element to an object while serializing to JSON using System.Text.Json

All, when executing the following code we are running into the following exception (in bold), we are trying to add the rootnode "test" to the end json result. we want to achieve this without anonymous objects or wrapper classes.

"Cannot write a JSON property within an array or as the first JSON token. Current token type is 'None'.

 internal static class Program
    {
        public static void Main(string[] args)
        {
            customer cust = new customer();
            cust.firstname = "first";
            cust.lastname = "last";

            Console.WriteLine(AddRootToJson("test", cust));
        }

        public static string AddRootToJson(string root, object obj)
        {
            var msSt = new MemoryStream {Position = 0};
            using var utf8JsonWriter = new Utf8JsonWriter(msSt);
            utf8JsonWriter.WriteStartObject(root);
            JsonSerializer.Serialize(utf8JsonWriter, obj);
            utf8JsonWriter.WriteEndObject();
            utf8JsonWriter.Flush();
            using var reader = new StreamReader(msSt);
            return reader.ReadToEnd();
        }
    }


    public class customer
    {
        public string firstname;
        public string lastname;
    }

Upvotes: 1

Views: 2885

Answers (2)

Guru Stron
Guru Stron

Reputation: 142833

First of all currently System.Text.Json does not support serializing fields, so you will need to change your class (see Support for public and non-public fields in docs):

public class customer
{
    public string firstname {get;set;}
    public string lastname {get;set;}
}

After that you can try next:

public static string AddRootToJson(string root, object obj)
{
    using var msSt = new MemoryStream();
    using var utf8JsonWriter = new Utf8JsonWriter(msSt);
    utf8JsonWriter.WriteStartObject();
    utf8JsonWriter.WritePropertyName(root);
    JsonSerializer.Serialize(utf8JsonWriter, obj);
    utf8JsonWriter.WriteEndObject();
    utf8JsonWriter.Flush();
    return Encoding.UTF8.GetString(msSt.ToArray());
}

Console.WriteLine(AddRootToJson("test", new customer {firstname = "first", lastname = "last"})); // prints {"test":{"firstname":"first","lastname":"last"}}

Upvotes: 5

Andrew Yanchak
Andrew Yanchak

Reputation: 45

If i have understood you correct you want to in the result something like this:

{"test",
    [
      {"first",
      "last"}
      ....
    ]
}

Just create for it another model:

public class FullModel
{
    public List<Customer> Customers {get;set;}
    public string Root {get;set;}
}

And change your Customer class:

public class Customer
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

Now, step by step:

public static void Main(string[] args)
    {
        List<Customer> customers = new List<Customers>();
        customers.Add(new Customer{FirstName="first",LastName="last"});
        FullModel fullModel = new FullModel
        {
            Root = "test",
            Customers = customers
        };
         
        Console.WriteLine(AddRootToJson(cust));
    }

public static string AddRootToJson(object obj)
    {
        var msSt = new MemoryStream {Position = 0};
        using var utf8JsonWriter = new Utf8JsonWriter(msSt);
        JsonSerializer.Serialize(utf8JsonWriter, obj);
        utf8JsonWriter.WriteEndObject();
        utf8JsonWriter.Flush();
        using var reader = new StreamReader(msSt);
        return reader.ReadToEnd();
    }

You can change method in depend of your view. Hope it will help you. Good luck.

Upvotes: 0

Related Questions