我使用json.net相对比较流利,但我一直在努力以简单的方式获取此值。
我觉得json.net应该能够推断出我正在尝试做的事情,这样我就不必为了获得自己想要的东西而花每一步。
下面是我第一次尝试失败,然后是第二次尝试。虽然第二次尝试确实可行,但我想简化代码,使其更像第一次尝试。
请注意,我不能假定“ C”对象是包含所需对象的对象。
var jt = JToken.Parse(@"{
""A"": {
""name"": ""object1"",
""order"": ""1"",
""type"": ""val""
},
""B"": {
""order"": ""2"",
""type"": ""val"",
},
""C"": {
""name"": ""object3"",
""type"": ""val"",
""answer"": ""Yes"", ""<------ comment"": ""this is the value I'm trying to get""
}
}");
//var firstAttempt = (jt.First(j => j["name"] == "object3"))["answer"]; // cannot be applied to operands of type 'JToken' and 'String'
var thisWorksFine = jt.First(a => a.ToObject<JProperty>()
.Value.ToObject<JObject>()["name"]?.ToString() == "object3")
.ToObject<JProperty>()
.Value["answer"];
所以我的问题是,有没有一种方法可以在不强制转换每个对象/属性的情况下获得值,并最终获得看起来更像我的第一次尝试的代码?如果我的第二次尝试或多或少是必须要做的,那很好。
答案 0 :(得分:1)
我已经使用QuickType为您的Json代码制作了一个模型,然后对其进行了解析并对其结果对象进行了过滤,这非常容易。 代码:
public class MyElement
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("order")]
public long Order { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("answer")]
public string Answer { get; set; }
}
并解析:
string json = @"{
""A"": {
""name"": ""object1"",
""order"": ""1"",
""type"": ""val""
},
""B"": {
""order"": ""2"",
""type"": ""val"",
},
""C"": {
""name"": ""object3"",
""type"": ""val"",
""answer"": ""Yes"",
}
}";
Dictionary<string, MyElement> elements = JsonConvert.DeserializeObject<Dictionary<string, MyElement>>(json);
string answerOfObject3 = elements.Values.FirstOrDefault(element => element.Name == "object3")?.Answer;
答案 1 :(得分:1)
您是否特别想始终在“ C”对象下获得答案?
如果是这样,您可以使用:
var jToken = JToken.Parse("{\r\n\t\"A\": {\r\n\t\t\"name\": \"object1\",\r\n\t\t\"order\": \"1\",\r\n\t\t\"type\": \"val\"\r\n\t},\r\n\t\"B\": {\r\n\t\t\"name\": \"object2\",\r\n\t\t\"order\": \"2\",\r\n\t\t\"type\": \"val\"\r\n\t},\r\n\t\"C\": {\r\n\t\t\"name\": \"object3\",\r\n\t\t\"type\": \"val\",\r\n\t\t\"answer\": \"Yes\"\r\n\t}\r\n}");
var answer = jToken.SelectToken("C.answer");
答案 2 :(得分:1)
您似乎跳过了不必要的循环。我会这样重写您的查询:
var answer = jt.Children<JProperty>()
.Where(jp => (string)jp.Value["name"] == "object3")
.Select(jp => (string)jp.Value["answer"])
.FirstOrDefault();
提琴:https://dotnetfiddle.net/blKne6
上面的内容可以简化为以下内容,这与您的第一次尝试有点接近:
var answer = (string)jt.Children<JProperty>()
.FirstOrDefault(jp => (string)jp.Value["name"] == "object3")
?.Value["answer"];