使用JObject.FromObject创建JObject会忽略DateFormatString [英] Creating JObject with JObject.FromObject ignores DateFormatString

查看:433
本文介绍了使用JObject.FromObject创建JObject会忽略DateFormatString的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to create a Newtonsoft JObject with a custom DateFormatSting ("yyyy-MM-ddTHH:mm:ssZ") using JOjbect.FromObject and I think there is a bug. My code is:

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

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

Here, JObject.FromObject seems to ignore the DateFormatString in my custom JsonSerializer.

我有一种解决方法,但是仍然好奇是否我做错了什么,或者是否有人看过?

I have a workaround, but still curious if I am doing something wrong, or if anyone else has seen this?

(解决方法)

JObject jBytes = Object.Parse(JsonConvert.SerializeObject(myObject, MyDateFormatString);

推荐答案

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

The reason you are seeing this is that JValue stores the DateTime as an actual DateTime structure copied from your object, not as a string. Therefore the DateFormatString is not applied during the conversion to JToken hierarchy. You can verify this by doing the following:

        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字符串表示形式时,需要应用该设置.不幸的是,在JToken上似乎没有方便的ToString()重载,允许指定DateFormatString.一种可能是序列化根令牌:

Thus the setting needs to be applied when you convert your JToken to its ultimate JSON string representation. Unfortunately, there doesn't seem to be a convenient ToString() overload on JToken allowing a DateFormatString to be specified. One possibility would be to serialize the root token:

        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()的开销.

This at least avoids the parsing overhead of JToken.Parse() in your workaround.

另一个选择是引入一种基于 JToken.ToString() TraceJsonWriter构造函数,它采用JsonSerializerSettings并应用适当的设置:

Another option would be introduce an extension method modeled on JToken.ToString() and the TraceJsonWriter constructor that takes a JsonSerializerSettings and applies the appropriate settings:

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"

原型小提琴.

这篇关于使用JObject.FromObject创建JObject会忽略DateFormatString的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆