我正在尝试使用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
发布评论