Reputation: 349
Yo Guys,
I'm currently trying to pass some mixed JSON, and was wondering if it was possible to do anything like the following?
struct example_data
{
public Dictionary<string, List<string>> information {get; set;}
}
class TestClass
{
static void Main(string[] args)
{
string test_string = @"{'EventSpecificInformation':
{
'measure':''
,'Long name':'test_name'
,'Short name':'test_s_name'
,'Description':''
,'Status':'Real (Imported)'
,'Viewers':['Everyone']
,'Modifiers':['Supervisor only']
,'calculation':''
}
}"
example_data deserialized_entry = JsonConvert.DeserializeObject<example_data>(test_string)
}
}
As you would expect the above code snippet fails, but I was hoping I could avoid wrapping each JSON entry in a JSON array or having to create a custom JSON reader in C#.
Any advice on the matter would be greatly appreciated.
Upvotes: 2
Views: 286
Reputation: 18155
Assuming that you do not want to use a static model,the problem with the code is that it doesn't match signature of your Json. The Json comprises of a Dictionary<string,Dictionary<string,List<string>>
. However, there is another concern.
Some of the values in inner Dictionary
is not List<string>
. Instead, they are strings. For example,
'Short name':'test_s_name'
For this purpose you need to use a a Custom JsonConverter
which if the values is not a array, converts the single string value to list. For example, consider the following Custom JsonConverter
.
class SingleOrArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(List<T>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<T>>();
}
return new List<T> { token.ToObject<T>() };
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Now, you could deserialize your Json as
string test_string = @"{'EventSpecificInformation':
{
'measure':''
,'Long name':'test_name'
,'Short name':'test_s_name'
,'Description':''
,'Status':'Real (Imported)'
,'Viewers':['Everyone']
,'Modifiers':['Supervisor only']
,'calculation':''
}
}";
var deserialized_entry = JsonConvert.DeserializeObject<Dictionary<string,Dictionary<string, List<string>>>>(test_string,new SingleOrArrayConverter<string>());
Output
Upvotes: 0
Reputation: 8004
As you would expect the above code snippet fails
string test_string = @"{'EventSpecificInformation':
{
'measure':''
,'Long name':'test_name'
,'Short name':'test_s_name'
,'Description':''
,'Status':'Real (Imported)'
,'Viewers':['Everyone']
,'Modifiers':['Supervisor only']
,'calculation':''
}
}"
In the above you're clearly missing an ending ;
at test_string
assignment, this wont compile, fix this first (I'm sure it's a type-o). Next, this isn't valid json
, you see all the '
in that json
, it should be quotes: "
. So in short, just replace the bad characters...
string test_string = @"{'EventSpecificInformation':
{
'measure':''
,'Long name':'test_name'
,'Short name':'test_s_name'
,'Description':''
,'Status':'Real (Imported)'
,'Viewers':['Everyone']
,'Modifiers':['Supervisor only']
,'calculation':''
}
}".Replace("'", "\"");
Note - As far as deserializing your json
, create a new question with what you've tried (after fixing this), what isn't working and expected output; you've multiple issues, let's address one at a time.
Upvotes: 2
Reputation: 4250
You can push the results to Dictionary
string test_string = @"{'EventSpecificInformation':
{
'measure':''
,'Long name':'test_name'
,'Short name':'test_s_name'
,'Description':''
,'Status':'Real (Imported)'
,'Viewers':['Everyone']
,'Modifiers':['Supervisor only']
,'calculation':''
}
}".Replace("'", "\"");
var results = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, object>>>(test_string);
Upvotes: 0
Reputation: 439
Sounds like what you're looking for is to parse a JSON string into a dynamic object, like so:
dynamic myObject = JsonConvert.DeserializeObject(@"{'EventSpecificInformation':
{
'measure':''
,'Long name':'test_name'
,'Short name':'test_s_name'
,'Description':''
,'Status':'Real (Imported)'
,'Viewers':['Everyone']
,'Modifiers':['Supervisor only']
,'calculation':''
}
}");
string desc = myObject.EventSpecificInformation.Description;
string longName = myObject.EventSpecificInformation["Long name"];
This is likely your best option if you don't have an explicit static model for your JSON input. For properties without a space in their name you can reference them directly using member access syntax, for those with a space you can reference them using indexer access syntax.
Upvotes: 3