Newtonsoft.Json DeserializeObject passing null for guid 00000000-0000-0000-0000-000000000000
If I understood correctly you have a problem initializing the Guid
on deserialization and you don't want to create a setter or use attributes for successful deserialization. Please note that I changed your MyIdentity
class by removing the constructor that accepted Guid
parameter since it's not necessary, changed the parsing of Guid
logic since it would have never initialize the convertableAsGuid
property correctly and created MyEvent
class since you didn't post it on your question. Also I created the MyCustomConverter
class which is used during the deserialization. Here are the classes:
public class MyCustomConverter : JsonConverter{ public override bool CanConvert(Type objectType) { return objectType == typeof (MyEvent); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jObject = JObject.Load(reader); existingValue = new MyEvent(new MyEntityId(jObject["Id"]["Value"].ToString()), jObject["Name"].ToString()); return existingValue; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); }}public class MyEvent{ public MyEntityId Id { get; set; } public string Name { get; set; } public MyEvent(MyEntityId id, string name) { Id = id; Name = name; }}public class MyEntityId : MyIdentity{ public MyEntityId(string identityValue) : base(identityValue) { }}public abstract class MyIdentity{ protected readonly bool convertableAsGuid; protected readonly string value; public string Value { get { return this.value; } } public MyIdentity(string identityValue) { this.value = identityValue; Guid guid; if (Guid.TryParse(identityValue, out guid)) this.convertableAsGuid = true; }}
And here is the serialization and deserialization logic:
static void Main(string[] args){ var evnt = new MyEvent(new MyEntityId(Guid.NewGuid().ToString()), "Jon Doe"); var eventHeaders = new Dictionary<string, object> { {"EventClrTypeName", evnt.GetType().AssemblyQualifiedName} }; var serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None }; var metadata = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(eventHeaders, serializerSettings)); var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(evnt, serializerSettings)); string dataAsString = Encoding.UTF8.GetString(data); var eventClrTypeName = JObject.Parse(Encoding.UTF8.GetString(metadata)).Property("EventClrTypeName").Value; var obj = JsonConvert.DeserializeObject<MyEvent>(dataAsString, new JsonConverter[] {new MyCustomConverter()});}