问题描述
我正在尝试使用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);
推荐答案
您看到的原因是JValue
将DateTime
存储为从对象复制的实际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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!