Creating JObject with JObject.FromObject ignores DateFormatString

☆樱花仙子☆ 提交于 2020-01-05 09:05:52

问题


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);

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?

(workaround)

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

回答1:


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));

The output will be ["System.DateTime", ...].

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"

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

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();
        }
    }
}

Then you can just do:

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

Prototype fiddle.



来源:https://stackoverflow.com/questions/32770455/creating-jobject-with-jobject-fromobject-ignores-dateformatstring

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!