【问题标题】:Deserializing LocalTime from JSON using JSON.NET and NodaTime results in NodaTime.Text.UnparsableValueException使用 JSON.NET 和 NodaTime 从 JSON 反序列化 LocalTime 会导致 NodaTime.Text.UnparsableValueException
【发布时间】:2016-09-23 18:39:00
【问题描述】:

我在将时间值反序列化为 LocalTime 时遇到问题 - 授予,我对 NodaTime 很陌生。我想导入一个以“HH:mm”格式列出时间的 Web 服务结果。除非我使用“hh:mm:ss.fff”格式的时间,否则我会遇到异常。有没有办法指定不同的模式并让“HH:mm”工作?

请看这段代码

using System;
using System.Collections.Generic;

using Newtonsoft.Json;
using NodaTime;
using NodaTime.Serialization.JsonNet;
using NodaTime.Text;    // Required for LocalTimePattern
namespace TestNodaTime
{
    class MyObject
    {
        [JsonProperty("var1")]
        public int MyProperty { get; set; }

        [JsonProperty("time")]
        public LocalTime MyTime { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string serializedObject1 = "[{\"var1\":\"42\",\"time\":\"01:02:03.004\"}]";
            string serializedObject2 = "[{\"var1\":\"42\",\"time\":\"01:02\"}]";

            JsonSerializerSettings jss = new JsonSerializerSettings();
            jss.ConfigureForNodaTime(DateTimeZoneProviders.Bcl);

            // This works - the pattern is "hh:mm:ss.fff"
            MyObject mo1 = JsonConvert.DeserializeObject<List<MyObject>>(serializedObject1, jss)[0];

            // This causes an exception  - the pattern is "HH:mm"
            MyObject mo2 = JsonConvert.DeserializeObject<List<MyObject>>(serializedObject2, jss)[0];
            /*
             * An unhandled exception of type 'NodaTime.Text.UnparsableValueException' occurred in Newtonsoft.Json.dll
             * Additional information: The value string does not match a quoted string in the pattern. 
             * Value being parsed: '01:02^'. (^ indicates error position.)
             */
        }
    }
}

抛出异常:

NodaTime.Text.UnparsableValueException 未处理 H结果=-2146233033 Message=值字符串与模式中带引号的字符串不匹配。正在解析的值:'01:02^'。 (^ 表示错误位置。) 来源=NodaTime 堆栈跟踪: 在 NodaTime.Text.ParseResult`1.GetValueOrThrow() 在 NodaTime.Text.ParseResult`1.get_Value() 在 NodaTime.Serialization.JsonNet.NodaPatternConverter`1.ReadJsonImpl(JsonReader reader, JsonSerializer serializer) 在 NodaTime.Serialization.JsonNet.NodaConverterBase`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter 转换器,JsonReader 阅读器,类型 objectType,对象现有值) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty 属性,JsonConverter propertyConverter,JsonContainerContract containerContract,JsonProperty containerProperty,JsonReader 阅读器,对象目标) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(对象 newObject,JsonReader 阅读器,JsonObjectContract 合同,JsonProperty 成员,字符串 id) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader 阅读器,类型 objectType,JsonContract 合同,JsonProperty 成员,JsonContainerContract containerContract,JsonProperty containerMember,对象现有值) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader 阅读器,类型 objectType,JsonContract 合同,JsonProperty 成员,JsonContainerContract containerContract,JsonProperty containerMember,对象现有值) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList 列表,JsonReader 阅读器,JsonArrayContract 合同,JsonProperty containerProperty,字符串 id) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader 阅读器,类型 objectType,JsonContract 合同,JsonProperty 成员,对象现有值,字符串 id) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader 阅读器,类型 objectType,JsonContract 合同,JsonProperty 成员,JsonContainerContract containerContract,JsonProperty containerMember,对象现有值) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader 阅读器,类型 objectType,布尔 checkAdditionalContent) 在 Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader 阅读器,类型 objectType) 在 Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader 阅读器,类型 objectType) 在 Newtonsoft.Json.JsonConvert.DeserializeObject(字符串值,类型类型,JsonSerializerSettings 设置) 在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](字符串值,JsonSerializerSettings 设置) 在 TestNodaTime.Program.Main(String[] args) 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() 内部异常:

【问题讨论】:

  • 所有版本都是“最新”稳定版本。

标签: c# json json.net deserialization nodatime


【解决方案1】:

您需要删除它在调用ConfigureForNodaTime 时添加的默认转换器。这些转换器使用默认的formats 并且不可配置(据我所知)。

JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ConfigureForNodaTime(DateTimeZoneProviders.Bcl);

jss.Converters.Remove(NodaConverters.LocalTimeConverter);
jss.Converters.Add(new NodaPatternConverter<LocalTime>(LocalTimePattern.CreateWithInvariantCulture("HH':'mm")));

MyObject mo2 = JsonConvert.DeserializeObject<List<MyObject>>(serializedObject2, jss)[0];

【讨论】:

  • 我必须添加一个:“使用 NodaTime.Text”。否则,完美。谢谢!
  • @DavidRogers 由于代码中的轻微 差异,我已回滚编辑。来自documentation - 在有效的情况下,: 总是指特定区域性的时间分隔符(不变区域性中的冒号) - 这意味着在 : 所在的本地运行代码是 不是时间分隔符,它将无法解析。指定 ':' 意味着我们正在寻找冒号,无论语言环境如何。
  • 它还与默认模式保持一致:github.com/nodatime/nodatime/blob/…
  • 感谢您的清理和链接!我认为这些撇号引起了我的问题,但我重新测试了,显然还有其他事情发生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
相关资源
最近更新 更多