I have a Rest API that accepts a JSON model consisting of its fields are dynamic GUIDs.
I tried multiple models and in all of them, I got an error.
This is the JSON:
{
"meta_data": {
"name": "myname"
},
"1122413f-2887-4789-a112-31d003f2703a": {
"ipadd": "1.1.1.1",
"host": "host"
},
"4432313f-2887-4789-a222-31d41231233a": {
"ipadd": "1.2.1.1",
"host": "h3st"
}
}
and this is the model:
public class RootObject
{
[JsonProperty("meta_data")]
public Metadata Metadata { get; set; }
public Dictionary<Guid, DeviceInfo> Devices { get; set; }
}
public class DeviceInfo
{
public string IpAdd { get; set; }
public string Host { get; set; }
}
and the controller:
[FromBody] RootObject jsonObj
The jsonObj
only contains the Metadata
and the dynamic field is always empty.
What can I do to overcome this?
It accepts when I send it under Devices
:
"Devices": {
"123...."
}
but this is not what I need.
If you are using .NET Core 3 and above, you can work with JsonExtensionDataAttribute
from System.Text.Json.Serialization.
You should add a new property for receiving the additional JSON element as Dictionary<string, JsonElement>
.
The dictionary's TKey value must be String, and TValue must be JsonElement or Object.
And assign it to the Devices
property with some data conversions.
using System.Text.Json.Serialization;
using System.Linq;
public class RootObject
{
[JsonPropertyName("meta_data")]
public Metadata Metadata { get; set; }
[JsonExtensionData]
public Dictionary<string, JsonElement> Extension { get; set; }
[JsonIgnore]
public Dictionary<Guid, DeviceInfo> Devices
{
get
{
if (Extension == null)
return null;
return Extension.ToDictionary(x => Guid.Parse(x.Key), v => JsonSerializer.Deserialize<DeviceInfo>(JsonSerializer.Serialize(v.Value)));
}
}
}
public class DeviceInfo
{
[JsonPropertyName("ipadd")]
public string IpAdd { get; set; }
[JsonPropertyName("host")]
public string Host { get; set; }
}
If you are using Newtonsoft.Json as the default serialization library/tool in your API/MVC application:
services.AddControllers()
.AddNewtonsoftJson();
You need to use the attributes/deserialization ways from Newtonsoft.Json.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class RootObject
{
[JsonProperty("meta_data")]
public Metadata Metadata { get; set; }
[JsonExtensionData]
public Dictionary<string, JToken> Extension { get; set; }
[JsonIgnore]
public Dictionary<Guid, DeviceInfo> Devices
{
get
{
if (Extension == null)
return null;
return Extension.ToDictionary(x => Guid.Parse(x.Key),
v => JObject.FromObject(v.Value)
.ToObject<DeviceInfo>());
}
}
}
public class DeviceInfo
{
[JsonProperty("ipadd")]
public string IpAdd { get; set; }
public string Host { get; set; }
}