我正在尝试使用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);
您看到这一点的原因是JValue
将DateTime
存储为从对象复制的实际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"
原型小提琴。