用JObject创建JObject.FromObject忽略DateFormatString



我正在尝试使用jojject创建一个具有自定义DateFormatSting ("yyyy-MM-ddTHH:mm:ssZ")的Newtonsoft JObject。FromObject,我觉得有个bug。我的代码是:

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

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

我有一个变通办法,但仍然好奇,如果我做错了什么,或者如果有人看到这个?

(解决方案)

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

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

        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。一种可能是序列化根令牌:

        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()TraceJsonWriter构造函数为模型的扩展方法,该构造函数接受JsonSerializerSettings并应用适当的设置:

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"

原型小提琴。

相关内容

  • 没有找到相关文章