I am looking for the equivalent of Golang's json: "inline"
tag with C#'s System.Text.Json
.
For example, I have the following class structure in C#:
class Outer{
public string Hello;
public Inner TheInner;
}
class Inner{
public string World;
}
And I want the serialized and deserialized JSON text to be
{
"Hello" : "example_value_01",
"World" : "example_value_02"
}
In Golang, I can achieve this with the following structure definition
type Outer struct{
Hello string
TheInner Inner `json: "inline"`
}
type Inner struct{
World string
}
However, I cannot find a decent way to do this in C#'s System.Text.Json
.
CodePudding user response:
There's not really any built-in functionality to do that in C#. However, you can write your own JSON converter like this:
public class InnerConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Inner inner = (Inner)value;
writer.WriteValue(inner.World);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Inner inner = new Inner();
inner.World = (string)reader.Value;
return inner;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Inner);
}
}
[JsonConverter(typeof(InnerConverter))]
public class Inner
{
public string World { get; set; }
}
This won't quite get you where you want, however, because the resulting JSON will look like this:
{
"Hello" : "example_value_01",
"TheInner" : "example_value_02"
}
So, you'll also have to modify Outer
:
public class Outer{
public string Hello { get; set; }
[JsonProperty("World")]
public Inner TheInner { get; set; }
}
This will give you the output you're looking for.
CodePudding user response:
To reach it in c# , you don't need any custom classes at all,you can use a dictionary
var dict = new Dictionary<string, string> {
{"Hello","example1"},
{"World","example2"}
};
var json= System.Text.Json.JsonSerializer.Serialize(dict,new JsonSerializerOptions { WriteIndented = true});
result
{
"Hello": "example1",
"World": "example2"
}
but if you want it a hard way it is much easier to make it using Newtonsoft.Json since Text.Json needs a custom serializer for almost everything
using Newtonsoft.Json;
var json = SerializeOuterObj(obj, "TheInner");
public string SerializeOuterObj(object outerObj, string innerObjectPropertyName)
{
var jsonParsed = JObject.FromObject(outerObj);
var prop = jsonParsed.Properties().Where(i => i.Name == innerObjectPropertyName).First();
prop.Remove();
foreach (var p in ((JObject)prop.Value).Properties())
jsonParsed.Add(p.Name, p.Value);
return jsonParsed.ToString();
}