I am attempting to take an object structured like so
public class Item
{
public Guid SourceTypeID {get;set;}
public Guid BrokerID {get;set;}
public double Latitude {get;set;}
public double Longitude {get;set;}
public DateTime TimeStamp {get;set;}
public object Payload {get;set;}
}
and serialize it with JSON.NET using a call like:
Item expected = new Item()
{
SourceTypeID = Guid.NewGuid(),
BrokerID = Guid.NewGuid(),
Latitude = 33.657145,
Longitude = -117.766684,
TimeStamp = DateTime.Now,
Payload = new byte[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
};
string jsonString = JsonConvert.SerializeObject(expected);
The payload member of the Item object will potentially hold any one primitive of a list of C# primitives (plus a few others like Guid), or an array of those types (as in the example, a byte array), or a "flat" object composed of any of those previously listed "primitives" (dynamically created).
When I perform the SerializeObject() call, the string that is produced contains:
{"Payload":"AAECAwQFBgcICQ==","SourceTypeID":"d8220a4b-75b1-4b7a-8112-b7bdae956a45",
"BrokerID":"951663c4-924e-4c86-a57a-7ed737501dbd",
"TimeStamp":"\/Date(1328202421559-0600)\/",
"Latitude":33.657145,"Longitude":-117.766684}
However when I make the deserializing call the item that is produced is partially incorrect
Item actual = JsonConvert.DeserializeObject<Item>(jsonString);
actual.SourceTypeID : {00000000-0000-0000-0000-000000000000}
actual.BrokerID : {951663c4-924e-4c86-a57a-7ed737501dbd}
actual.Latitude : 33.657145;
actual.Longitude : -117.766684;
actual.TimeStamp : {2/2/2012 11:07:01 AM}
actual.Payload : null
The SourceTypeID member (Guid), and the Payload member (object, holding a byte[]), are both incorrect. The serialized string seems to hold the right identity for the guid, but not for the byte array.
I see that an alternate signatureof SerializeObject is
SerializeObject(object value, params JsonConverter[] converters);
Is this the correct way to inform the de/serialization engine about types that it apparently handles wrong? Since I am working with a limited set of "primitives" at the core of my object, if I could create a set of converters for each of those types, would that solve my problem?
I want to avoid reinventing the wheel if possible, as it seems that this would be a problem that has already been handled gracefully, and I'd like to leverage something like that if available.
Payload will be deserialized as a string unless you place a [JsonProperty] attribute with TypeNameHandling enabled on it, otherwise the deserializer won't know what to deserialize it as.
I haven't been able to duplicate the problem you got with some properties being null using the latest source code at http://json.codeplex.com/SourceControl/list/changesets
This appears to be an actual bug in JSON.NET.
It's not idea, but a workaround might be to have a two-stage serialization. The first, the object that actually gets serialized to/from JSON, would consist only of fields/properties with string
type. The second object (the one your server-side code would use) would be an object that is converted to strong types manually.
Not ideal, but possible. Additonally, you could consider using the DataContractJsonSerializer, which does a pretty good job of handling byte arrays and guids IME. Dates are still pretty sucky, but that's mostly the fault of Javascript.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With