【问题标题】:JSON JObject.Parse modifies json stringJSON JObject.Parse 修改 json 字符串
【发布时间】:2018-03-26 12:02:35
【问题描述】:

我收到了格式的传入 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的变化?

【问题讨论】:

  • DateTime.ParseExact 有一个重载,它允许你传递多种格式msdn.microsoft.com/en-us/library/332de853(v=vs.110).aspx
  • 等等,你真的是在失去精度,还是只是零?
  • @Nyerguds 只是零。精度是一样的
  • 那么,这不是说它已经已经被什么东西解析了吗?否则它无法知道那些零是多余的。
  • 我不明白你在问什么。只有一种解析。从正确的字符串到不正确的 jsonobject。然后,我试图从抛出不正确格式异常的不正确 jsonobject 解析 DateTime。

标签: c# json parsing uwp


【解决方案1】:

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

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 默认情况下。

您可以避免将看起来像日期的字符串解析为 .NET DateTime 对象,方法是将 json 解析为 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>>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 2021-04-29
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2015-06-19
    相关资源
    最近更新 更多