I'm using a service which returns a json
.
I have a key-value object where the key is a string
and the value is an object
and I know where to cast the object based on the key.
It will look something like:
{
"key1": "This is key 1",
"key2": 12,
"key3": ["Key 3 first item", "Key 3 second item"]
}
With simple types (eg) strings
, long
, int
etc. There is no problem.
My problem starts when I receive an array
(key3).
My c# code will look something like this:
Dictionary<string, object> values = GetValuesFromTheService();
string str = (string)values["key1"]; // Ok
long lng = (long)values["key2"]; // Ok
List<string> strs = (List<string>)values["key3"]; // BAD
key3 is actually a JArray
and not a List<string>
- I guess this happens since I'm using an object
as a value and not being more specific (a List<object>
will also be better then a JArray
).
Is there anything I can do about this?
You should be able to parse the entire object to a jObject and then select the keys back out to the types you need. This is untested but the basic idea.
var j = JObject.Parse(GetValuesFromTheService());
string str = (string)j.SelectToken("key1");
long lng = (long)j.SelectToken("key2");
var strs = (List<string>)j.SelectToken("key3");
I have a similar situation when attempting to (de)serialize some of our custom enumerations. For the solution, I created a custom JsonConvertor. Here's the code I use for that...
public class EnumerationConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var enm = (Enumeration)value;
writer.WriteValue(enm.Value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
{
return null;
}
int value;
if (reader.ValueType == typeof(Int64))
{
value = Convert.ToInt32(reader.Value);
}
else
{
value = (int)reader.Value;
}
return Enumeration.FromValueOrDefault(objectType, value);
}
public override bool CanConvert(Type objectType)
{
if (objectType.BaseType == null) return false;
return objectType.BaseType.Name == "Enumeration";
}
}
Then, when I want to invoke it and pull the json back into my object, here's the line for that one...
JsonConvert.DeserializeObject<List<CustomObjectDto>>(req.Content.ReadAsStringAsync().Result, new EnumerationConverter());
Nice thing is that this becomes universally available and the CustomObjectDto can just have an instance of this magic dictionary in it as a property...or even multiple...and will apply the conversion on only the properties that match according to the logic in the convertor...hope that helps.
And here's a link to a similar topic --> http://blog.maskalik.com/asp-net/json-net-implement-custom-serialization/
如果key3
是string
值的JArray
,则可以执行以下操作:
List<string> strs = ((JArray)values["key3"]).Select(t => t.Value<string>()).ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.