Reputation: 45
I've been trying create c# classes to map to a JSON format required by a service. But failing to find the right answer.
Here is the JSON:
{
"request": {
"path": "1",
"coverages": {
"path": "2",
"broadcastCoverage": {
"path": "3",
"name": "First Coverage",
"channel": "Channel 9",
"callSign": "DSOTM"
},
"internetCoverage": {
"path": "4",
"name": "Second Coverage",
"url": "www.stackoverflow.com"
},
"thirdCoverage": {
"path": "5",
"name": "Third Coverage",
"differentProperty": "Units"
}
}
}
}
If I put this into a JSON to C# converter I get the following:
public class BroadcastCoverage
{
public string path { get; set; }
public string name { get; set; }
public string channel { get; set; }
public string callSign { get; set; }
}
public class InternetCoverage
{
public string path { get; set; }
public string name { get; set; }
public string url { get; set; }
}
public class ThirdCoverage
{
public string path { get; set; }
public string name { get; set; }
public string differentProperty { get; set; }
}
public class Coverages
{
public string path { get; set; }
public BroadcastCoverage broadcastCoverage { get; set; }
public InternetCoverage internetCoverage { get; set; }
public ThirdCoverage thirdCoverage { get; set; }
}
public class Request
{
public string path { get; set; }
public Coverages coverages { get; set; }
}
public class RootObject
{
public Request request { get; set; }
}
But I need different types of Coverages (Broadcast, Internet, others) to be variable so I tried taking those out of the Coverages class and added a property:
public Dictionary<string, CoverageBase> CoverageList { get; set; }
Which will allow me to choose which coverages to include, the problem then becomes the CoverageList property name is in the JSON when it is serialized. I essentially would like a key/value (string, CoverageBase) without the property name.
Is there a way to add key value pairs without having the property name in the JSON? I've seen examples where this is done at the root object level but I haven't been able to find any example where it nested within the JSON.
If this can't be done with a simple object model what would be a recommended method to get the JSON built?
UPDATE: I like the answer that utilizes JsonSubTypes as it doesn't require much code, however I can't use a 3rd party library outside of json.net. Is there a way to accomplish this using a JsonConverter?
Upvotes: 1
Views: 335
Reputation: 894
I think its possible as checked here, however it seems your app needs to reconstruct the json in a format where it includes the C# typings. More documentation here.
EDIT: Thanks to dbc's reference I was able to dive in to the JsonSubtypes and its pretty easy to implement.
Here's my code base structure.
[JsonConverter(typeof(JsonSubtypes))]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(BroadcastCoverage), "channel")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(InternetCoverage), "url")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(ThirdCoverage), "differentProperty")]
public class CoverageBase
{
public string path { get; set; }
public string name { get; set; }
}
public class BroadcastCoverage : CoverageBase
{
public string channel { get; set; }
public string callSign { get; set; }
}
public class InternetCoverage : CoverageBase
{
public string url { get; set; }
}
public class ThirdCoverage : CoverageBase
{
public string differentProperty { get; set; }
}
public class Request
{
public string path { get; set; }
public List<CoverageBase> coverages { get; set; }
}
However the Json you're receiving was not quite ideally structured, so I did some reformatting just to let it to be properly parsed.
string json = "{\"request\":{\"path\":\"1\",\"coverages\":{\"path\":\"2\",\"broadcastCoverage\":{\"path\":\"3\",\"name\":\"First Coverage\",\"channel\":\"Channel 9\",\"callSign\":\"DSOTM\"},\"internetCoverage\":{\"path\":\"4\",\"name\":\"Second Coverage\",\"url\":\"www.stackoverflow.com\"},\"thirdCoverage\":{\"path\":\"5\",\"name\":\"Third Coverage\",\"differentProperty\":\"Units\"}}}}";
var jsonReq = JObject.Parse(json);
var pathVal = jsonReq["request"]["path"].Value<string>();
var coverageObjects = jsonReq["request"]["coverages"].Value<JObject>();
var filteredObjects = coverageObjects.Children().Where(x => x.Value<JProperty>().Name.EndsWith("Coverage"));
var dictionary = filteredObjects.Select(x => new KeyValuePair<string, string>(x.Value<JProperty>().Name, x.Value<JProperty>().Value.ToString()));
// reformatted Json
var newJson = "{ \"path\":\"" + pathVal + "\", \"coverages\" : [" + String.Join(",", dictionary.Select(x => x.Value).ToList()) + "]}";
Request reqC = JsonConvert.DeserializeObject<Request>(newJson);
Upvotes: 2