问题
I have a json string that looks like the following
{
"1ST": {
"name": "One",
"symbol": "1st"
},
"2ND": {
"name": "Two",
"symbol": "2nd"
}
}
Im trying to Serialize it down to a C# object. It looks like it is creating a Dictionary, so i have created the following structure
public class Response
{
public Dictionary<string, Item> Objects { get; set; }
}
public class Item
{
public string name { get; set; }
public string symbol { get; set; }
}
And during serialization running the following
response = JsonConvert.DeserializeObject<Response>(jsonString);
It doesnt throw an error on Deserialization, but my response just comes back as null. What am i missing?
回答1:
You've got the right basic idea, but you've got an extra Objects
property that you don't really want: your JSON is the dictionary, effectively. You can deserialize it directly to a Dictionary<string, Item>>
. Here's an example:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
public class Item
{
public string Name { get; set; }
public string Symbol { get; set; }
public override string ToString() => $"{Name}/{Symbol}";
}
public class Test
{
static void Main()
{
var json = File.ReadAllText("test.json");
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);
foreach (var entry in dictionary)
{
Console.WriteLine($"{entry.Key}: {entry.Value}");
}
}
}
Output:
1ST: One/1st
2ND: Two/2nd
Now if you need your Response
type, there are various options:
- Make that derive from
Dictionary<string, Item>
and remove theObjects
property. (Not good if you need theObjects
property.) - Deserialize to the dictionary, but then create a new
Response
object and assign the property yourself. (Not good if the response is part of another type.) - Investigate whether there's some attribute for Json.NET to treat
Objects
as a sort of "root" property.
I've had some luck with the last aspect, but not a complete solution. If you change Objects
to a Dictionary<string, JToken>
then you can apply the [JsonExtensionData]
to it, which makes it act as a default dictionary for any unmatched property. However, I haven't found a way of persuading Json.NET to use that attribute and perform the appropriate conversion. You could create a dictionary which performed the conversion from JToken
to Item
(using regular Json.NET code) every time an entry was added to it, and then added that value to another dictionary - but that's pretty ugly. This may just be a case that Json.NET doesn't handle.
回答2:
Using strong type object is recommended but another approach you can use dynamic type that will be evaluate during runtime.
Please take a look the code below.
Please note that I change variable name because we cannot define variable start with numeric in C#.
using Newtonsoft.Json;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var jsonString = @"{
'First': {
'name': 'One',
'symbol': '1st'
},
'Second': {
'name': 'Two',
'symbol': '2nd'
}
}";
//If you want to access using strong type.
var response = JsonConvert.DeserializeObject<Response>(jsonString);
var secondSymbol = response.Second.symbol.ToString();
System.Console.WriteLine(secondSymbol);
//If you want to access using dynamic type, will evalute in runtime.
var responseDynamic = JsonConvert.DeserializeObject<dynamic>(jsonString);
var secondSymbolDynamic = responseDynamic.Second.symbol.ToString() ;
System.Console.WriteLine(secondSymbolDynamic);
System.Console.ReadLine();
}
public class Response
{
public Item First { get; set; }
public Item Second { get; set; }
}
public class Item
{
public string name { get; set; }
public string symbol { get; set; }
}
}
}
Hope it will be useful. :)
来源:https://stackoverflow.com/questions/49932943/deserializing-json-without-unique-property-name