我正在尝试使用JOjbect.FromObject使用自定义DateFormatSting(“yyyy-MM-ddTHH:mm:ssZ”)创建一个Newtonsoft JObject,我认为存在一个错误。我的代码是:
b.vm.provision :shell, :inline => "cf-agent -KI"
b.vm.provision :shell, :inline => "echo 'Running the syncdb now'"
b.vm.provision :shell, :inline => "source ~/.bashrc && cd / && /devbox/barista/manage.py syncdb --noinput --settings=test_app.settings.dev", :privileged => "false"
这里,JObject.FromObject似乎忽略了自定义JsonSerializer中的DateFormatString。
我有一个解决方法,但是如果我做错了,或者其他人看到过这个问题,我仍然很好奇吗?
(解决方法)
JObject jBytes = JObject.FromObject(myObject, MyJsonSerializer);
答案 0 :(得分:2)
您看到这一点的原因是JValue
将DateTime
存储为从您的对象复制的实际DateTime
结构,而不是字符串。因此,在转换为DateFormatString
层次结构期间,不会应用JToken
。您可以通过执行以下操作来验证这一点:
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字符串表示时,需要应用该设置。不幸的是,ToString()
上的JToken
重载似乎不允许指定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()
为模型的扩展方法和一个JsonSerializerSettings
的{{3}}并应用相应的设置:
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"