0

Ok so I have these classes to process an Event of an OrderUploadFile creation:

public class ProcessOrderXlsEvent : ProcessFileBaseEvent
{
    public Guid Id { get; set; }
}
public class ProcessFileBaseEvent
{
    public OrderUploadFile? Message { get; set; }
    public DateTime Timestamp { get; set; }
}

I have a class OrderUploadFile that inherits from Entity (which is used by other classes)

public class OrderUploadFile : Entity
{
    public string FileNameOriginal { get; private set; }

    public string ContentType { get; private set; }

    public long ContentLength { get; private set; }

    public OrderUploadFile(
        string fileNameOriginal,
        string contentType,
        long contentLength)
    {
        FileNameOriginal = fileNameOriginal;
        ContentType = contentType;
        ContentLength = contentLength;
    }
}

Entity:

public abstract class Entity
{
    public Guid Id { get; private set; }
    public string CreatedBy { get; set; }
    public DateTime CreatedAt { get; private set; }
    public string? UpdatedBy { get; set; }
    public DateTime? UpdatedAt { get; set; }

    protected Entity()
    {
        Id = Guid.NewGuid();
    }
}

A message comes with this structure:

{
  "Id": "dasadsa-dasda-dasda-42fdsa-1312dswas",
  "Message": {
    "FileNameOriginal": "fileName-etc.xlsm",
    "ContentType": "application/vnd.ms-excel.sheet.macroEnabled.12",
    "ContentLength": 153121,
    "Id": "432424dasdad-fdsfsd312-dsa21-312dsa-ds212",
    "CreatedBy": null,
    "CreatedAt": "0001-01-01T00:00:00",
    "UpdatedBy": null,
    "UpdatedAt": null
  },
  "Timestamp": "2022-10-21T09:25:16.9305165Z"
}

The message, when it arrives, actually has the correct id of the OrderUploadFile class, but when deserialized, this id is not recognized. If I comment out the Entity constructor's Id assignment line to test, the OrderUploadFile's Id is left with an empty Guid (example 0000-0000-0000-etc).

This is the way of deserialization (As MessageBody being the message above):

JsonConvert.DeserializeObject<ProcessOrderXlsEvent>(args.MessageBody);

How can I get the Id inside the message to be correctly assigned to OrderUploadFile? Is it possible to do this even inheriting from Entity?

zupp
  • 96
  • 7
  • 1
    GUIDs aren't JSON primitives which might explain why this isn't working (not 100% sure how Newtonsoft's library handles this but the native .NET one wouldn't work with it as far as I remember). Try setting up your GUID as a string in the object you're deserialising into (effectively making it into a DTO), then using Guid.TryParse to get the object you need. – madmonk46 Oct 21 '22 at 10:09
  • 1
    Probably a duplicate of this question?: https://stackoverflow.com/questions/70589339/guid-passed-in-json-being-deserialized-as-00000000-0000-0000-0000-000000000000 – ProgrammingLlama Oct 21 '22 at 10:11
  • @ProgrammingLlama Not so sure it is, the accessors all look right and the GUID looks to be in the correct format as well. – madmonk46 Oct 21 '22 at 10:17
  • @madmonk46 Yeah, GUID deserialization works out-of-the-box for me, but that people were suggesting a converter for GUIDs on that question makes me wonder if OP isn't using some older version of JSON.NET which didn't support it. That's why I was hesitant to just mark this question as a duplicate, since it works for me anyway. – ProgrammingLlama Oct 21 '22 at 10:20
  • To create an _OrderUploadFile_ instance, its constructor has to be used. Does it allow passing the entity ID? No. Can the entity ID property being set? It doesn't have a public setter. So, the observed behavior is perfectly matching your implementation. –  Oct 21 '22 at 10:21
  • 1
    "dasadsa-dasda-dasda-42fdsa-1312dswas" doesn't look correct GUID. Not sure if you are using Newtonsoft.JSON. Changing the Id property with a valid GUID, works fine. Did you try that? – tyrion Oct 21 '22 at 10:21
  • 1
    That's a good point. Is that actually the "GUID" you're receiving? I assumed you'd just obfuscated your data, but s and w aren't in the character set 012345679ABCDEF so not valid in a GUID. Substituting the fake GUID values for real GUID values certainly does make it all deserialize correctly with the latest version of JSON.NET. – ProgrammingLlama Oct 21 '22 at 10:23
  • @ProgrammingLlama, "_make it all deserialize correctly with the latest version of JSON.NET._" Does it really, though? Note that Entity.Id has only a private setter (and no constructor allowing for passing the Id into it). Unless you utilize some Json.Net attribute annotations or some other means, Entity.Id won't receive the respective value from the json. (Dotnetfiddle showing this behavior: https://dotnetfiddle.net/z1OUbW) –  Oct 21 '22 at 10:30
  • @ProgrammingLlama I just changed the GUID value to post here, in fact i'm receiving a GUID. Removing the private set from Entity solved the problem, but i'm not sure if this is the best way to do it (since other classes use Entity and the Id should has a private set). – zupp Oct 21 '22 at 10:33
  • You can decorate `Id` with `[JsonProperty]`. Or allow to pass id in constructor. There are also ways to fix this using custom contract resolvers if you don't want to change the models. – Evk Oct 21 '22 at 10:35

0 Answers0