问题
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);
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?
(workaround)
JObject jBytes = Object.Parse(JsonConvert.SerializeObject(myObject, MyDateFormatString);
回答1:
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));
The output will be ["System.DateTime", ...]
.
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"
This at least avoids the parsing overhead of JToken.Parse()
in your workaround.
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();
}
}
}
Then you can just do:
var settings = new JsonSerializerSettings { DateFormatString = "yyyy/MM/dd" };
var json = jBytes.ToString(Formatting.Indented, settings); // Outputs "2015/09/24"
Prototype fiddle.
来源:https://stackoverflow.com/questions/32770455/creating-jobject-with-jobject-fromobject-ignores-dateformatstring