使用JObject.FromObject创建JObject会忽略DateFormatString

时间:2015-09-24 20:36:35

标签: c# json.net

我正在尝试使用JOjbect.FromObject使用自定义DateFormatSting(“yyyy-MM-ddTHH:mm:ssZ”)创建一个Newtonsoft JObject,我认为存在一个错误。我的代码是:

b.vm.provision :shell, :inline => "cf-agent -KI"
b.vm.provision :shell, :inline => "echo 'Running the syncdb now'"
b.vm.provision :shell, :inline => "source ~/.bashrc && cd / && /devbox/barista/manage.py syncdb --noinput --settings=test_app.settings.dev", :privileged => "false"

这里,JObject.FromObject似乎忽略了自定义JsonSerializer中的DateFormatString。

我有一个解决方法,但是如果我做错了,或者其他人看到过这个问题,我仍然很好奇吗?

(解决方法)

JObject jBytes = JObject.FromObject(myObject, MyJsonSerializer);

1 个答案:

答案 0 :(得分:2)

您看到这一点的原因是JValueDateTime 存储为从您的对象复制的实际DateTime结构,而不是字符串。因此,在转换为DateFormatString层次结构期间,不会应用JToken。您可以通过执行以下操作来验证这一点:

        var types = jBytes.DescendantsAndSelf().OfType<JValue>().Where(v => v.Type == JTokenType.Date).Select(v => v.Value.GetType().FullName);
        Debug.WriteLine(JsonConvert.SerializeObject(types, Formatting.None));

输出为["System.DateTime", ...]

因此,当您将JToken转换为其最终的JSON字符串表示时,需要应用该设置。不幸的是,ToString()上的JToken重载似乎不允许指定DateFormatString。一种可能性是序列化根令牌:

        var settings = new JsonSerializerSettings { DateFormatString = "yyyy/MM/dd" };

        var jBytes = JObject.FromObject(myObject);

        var json = JsonConvert.SerializeObject(jBytes, Formatting.Indented, settings); // Outputs "2015/09/24"

这至少可以避免解决方法中JToken.Parse()的解析开销。

另一种选择是引入一个以JToken.ToString()为模型的扩展方法和一个JsonSerializerSettings的{​​{3}}并应用相应的设置:

public static class JsonExtensions
{
    public static string ToString(this JToken token, Formatting formatting = Formatting.Indented, JsonSerializerSettings settings = null)
    {
        using (var sw = new StringWriter(CultureInfo.InvariantCulture))
        {
            using (var jsonWriter = new JsonTextWriter(sw))
            {
                jsonWriter.Formatting = formatting;
                jsonWriter.Culture = CultureInfo.InvariantCulture;
                if (settings != null)
                {
                    jsonWriter.DateFormatHandling = settings.DateFormatHandling;
                    jsonWriter.DateFormatString = settings.DateFormatString;
                    jsonWriter.DateTimeZoneHandling = settings.DateTimeZoneHandling;
                    jsonWriter.FloatFormatHandling = settings.FloatFormatHandling;
                    jsonWriter.StringEscapeHandling = settings.StringEscapeHandling;
                }
                token.WriteTo(jsonWriter);
            }
            return sw.ToString();
        }
    }
}

然后你可以这样做:

        var settings = new JsonSerializerSettings { DateFormatString = "yyyy/MM/dd" };
        var json = jBytes.ToString(Formatting.Indented, settings); // Outputs "2015/09/24"

原型TraceJsonWriter constructor