How to Serialize a C# Anonymous Type to a JSON String

How do I serialize a C# anonymous type to a JSON string?

Try the JavaScriptSerializer instead of the DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);

How to declare anonymous type for Json serialization, if one of the Json keys contains a dot?

Json can generally be represented using arrays, dictionaries and anonymous objects.

The first part of your Json can be generated as follows:

return JsonConvert.SerializeObject(new
{
query = new
{
@bool = new
{
must = new[]
{
new
{
term = new Dictionary<string, object>
{
["firstname.keyword"] = string.Empty,
}
}
}
}
}
});

Serialize anonymous type with literal JSON properties

If you have Json.Net installed you can use a JRaw:

public ContentResult Something()
{
var literalJson = "{\"a\":1,\"b\":2}";

var resp = new
{
result = "success",
responseTime = DateTimeOffset.Now,
data = new Newtonsoft.Json.Linq.JRaw(literalJson)
};

return Content(JsonConvert.SerializeObject(resp), "application/json", Encoding.UTF8);
}

But note that you will need to use Json.Net's serializer for this to work. That is why I changed the above code to use JsonConvert.SerializeObject and return a ContentResult rather than the using the controller's Json method like you had shown originally. The Json method uses JavaScriptSerializer internally, which doesn't know how to handle a JRaw.

System.Text.Json serialization against an anonymous object

DotNetFiddler

If you want to serialize the objects, why not initialize them as objects? Is there a requirement to create it strong typed?

    public static void Test()
{
var items = new List<object>() { new Class1 { Foo = "foo1", Bar1 = "Bar1" }, new Class2 { Foo = "foo1", Bar2 = "Bar2" } };
int totalCount = 1;
int min = 2;
int max = 3;

var root = new
{
totalCount,
min,
max,
items,
};

var json = JsonSerializer.Serialize<object>(root, new JsonSerializerOptions { WriteIndented = true, });

Console.WriteLine(json);
}

If you create the items as List<object>, you dont have to change or do anything. This might be a cleaner way instead of casting each of them to object at time of creating the object.

Deserialize anonymous type with System.Text.Json

As of .Net 5.0, deserialization of immutable types -- and thus anonymous types -- is supported by System.Text.Json. From How to use immutable types and non-public accessors with System.Text.Json:

System.Text.Json can use a parameterized constructor, which makes it possible to deserialize an immutable class or struct. For a class, if the only constructor is a parameterized one, that constructor will be used.

As anonymous types have exactly one constructor, they can now be deserialized successfully. To do so, define a helper method like so:

public static partial class JsonSerializerExtensions
{
public static T? DeserializeAnonymousType<T>(string json, T anonymousTypeObject, JsonSerializerOptions? options = default)
=> JsonSerializer.Deserialize<T>(json, options);

public static ValueTask<TValue?> DeserializeAnonymousTypeAsync<TValue>(Stream stream, TValue anonymousTypeObject, JsonSerializerOptions? options = default, CancellationToken cancellationToken = default)
=> JsonSerializer.DeserializeAsync<TValue>(stream, options, cancellationToken); // Method to deserialize from a stream added for completeness
}

And now you can do:

var token = JsonSerializerExtensions.DeserializeAnonymousType(jsonStr, new { token = "" }).token;

Demo fiddle here.



Related Topics



Leave a reply



Submit