JSON JObject.Parse修改json字符串

时间:2018-03-26 12:02:36

标签: c# json parsing uwp

我的格式是Json:

{
    "Type": "value",
    "Name": "MeteoStation",
    "UniqueAdress": "2C:3A:E8:0F:10:76",
    "valuesList": [{
        "Value": 23.00,
        "Unit": "C",
        "Type": "temperature",
        "SourceUniqAdress": "2C:3A:E8:0F:10:76",
        "TimeCaptured": "2018-03-26T09:36:13.200Z"
    }]
}

在我的程序中,我想创建对象IValuePacket,它是值列表中的一个值。

JObject jobject = JObject.Parse(incomingJson);
var settings = new JsonSerializerSettings {
    NullValueHandling = NullValueHandling.Ignore,
    MissingMemberHandling = MissingMemberHandling.Ignore
};
var incommingMessage = JsonConvert.DeserializeObject<MessageEncapsulation>(incomingJson);
string Type = incommingMessage.Type;
string name = incommingMessage.Name;

if (string.IsNullOrWhiteSpace(name))
    name = "no name";

if (Type.ToLower().Equals("value")) {
    var values = JsonConvert.DeserializeObject<List<IValuePacket>>(jobject["valuesList"].ToString());
}

一切都很好,直到我收到了上面提到的这个json。 JObject.Parse修改值TimeCaptured和jobject看起来像:

{
"Type": "value",
"Name": "Meteostation",
"UniqueAdress": "2C:3A:E8:0F:10:76",
"valuesList": [{
    "Value": 23.00,
    "Unit": "C",
    "Type": "temperature",
    "SourceUniqAdress": "2C:3A:E8:0F:10:76",
    "TimeCaptured": "2018-03-26T09:36:13.2Z"
}]}

差别不大,但DateTime.ParseExact(value, "yyyy-MM-ddThh:mm:ss.fffZ", System.Globalization.CultureInfo.InvariantCulture);无法解析新值。实际上,我发送201毫秒而不是200毫秒。它有效,但我希望将来有充足的时间用于未来的原因。

在解析过程中,如何避免在Json中进行更改?

1 个答案:

答案 0 :(得分:1)

它不会真正修改您的字符串,只是在您调用DateTime时将日期字符串解析为JObject.Parse对象。如果你这样做:

var obj = JObject.Parse(json);
var values = (JArray) obj["valuesList"];
var time = (JValue) values[0]["TimeCaptured"];
Console.WriteLine(time.Value.GetType());

您注意到time.Value的类型为DateTime。然后你这样做:

JsonConvert.DeserializeObject<List<IValuePacket>>(jobject["valuesList"].ToString());

通过这样做你将valueList转换回json,但现在TimeCapturedDateTime而不是字符串,所以DateTime对象使用任何东西转换为json字符串默认情况下,JSON.NET使用日期时间格式。

您可以通过将json解析为DateTime来避免将类似于日期的字符串解析为.NET JObject对象:

JObject obj;
using (var reader = new JsonTextReader(new StringReader(json))) {
    // DateParseHandling.None is what you need
    reader.DateParseHandling = DateParseHandling.None;
    obj = JObject.Load(reader);
}

然后TimeCaptured的类型将是字符串,正如您所期望的那样。

旁注:无需将JToken转换回字符串,然后在该字符串上调用JsonConvert.Deserialize。相反,这样做:

var values = obj["valuesList"].ToObject<List<IValuePacket>>();