0

Using C#, Newtonsoft.Json 13.0.2 and having the following possible JSONs:

Json type 1 ---------------------

{
  "type": "succeeded",
  "event_date": "2023",
  "transaction": {
    "id": "AAA",
    "authorization": "123",
    "operation_type": "456"
  }
}

Json type 2 ---------------------

{
  "type": "failed",
  "event_date": "2023",
  "failureReport": {
    "id": "AAA",
    "failureType": "123"      
  }
}

I'm using the following code to deserialize any of the two objects as follows:

[Table("MySql_Test_Table")]

public class TestClass
{
[Key]
[JsonPropertyName("id")]
public int id { get; set; }

[JsonPropertyName("event_date")]
public DateTime? event_date { get; set; }

[JsonPropertyName("type")]
public String? type { get; set; }

[JsonPropertyName("transaction.id")]
public String? transaction_id { get; set; }  

[JsonPropertyName("transaction.authorization")]
public String? authorization{ get; set; }

[JsonPropertyName("transaction.operation_type")]
public String? operation_type{ get; set; }

[JsonPropertyName("failureReport.id")]
public String? failureReportId{ get; set; }

[JsonPropertyName("failureReport.failureType")]
public String? failureReportType{ get; set; }

}

TestClass testClass = Newtonsoft.Json.JsonConvert.DeserializeObject<TestClass>(oneOfTwoPossiblejsonTexts.ToString());

//...Code for saving testClass using EntityFramrwork...

With the aforementioned code I'm able to get the values for type and event_date without problem. However I'm unable to populate id, authorization, operation_type, failureReportId, orfailureReportType. I guess the problem is my [JsonPropertyName] tag. Please, how could I correct it to access the required values?

Felipe La Rotta
  • 343
  • 3
  • 13
  • [`JsonPropertyNameAttribute`](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonpropertynameattribute) is for the System.Text.Json serializer, but you are using Json.NET for deserialization. You must switch to System.Text.Json or replace the attributes with [`[JsonProperty("some name")]`](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonPropertyAttribute.htm) from Newtonsoft.Json. See [Why JsonConvert.DeserializeObject ignoring JsonPropertyName attributes?](https://stackoverflow.com/q/69584498). – dbc Feb 10 '23 at 22:29
  • Also, are you trying to use JSONPath syntax in `[JsonPropertyName("failureReport.failureType")]` to select property values in nested objects? If so then neither Json.NET nor System.Text.Json has any such built-in functionality. If that is what you are trying to do, and you stick with Json.NET, see maybe [this answer](https://stackoverflow.com/a/33094930) by Brian Rogers to [Can I specify a path in an attribute to map a property in my class to a child property in my JSON?](https://stackoverflow.com/q/33088462). – dbc Feb 10 '23 at 22:31

2 Answers2

0

Likely, the safest bet is to create corresponding C# types:

public class TestClass
{
[Key]
[JsonPropertyName("id")]
public int id { get; set; }

[JsonPropertyName("event_date")]
public DateTime? event_date { get; set; }

[JsonPropertyName("type")]
public String? type { get; set; }

public TransactionType Transaction { get; set; }

public FailureReportType FailureReport { get; set; }
}

public class TransactionType
{
[JsonPropertyName("id")]
public String? transaction_id { get; set; }  

[JsonPropertyName("authorization")]
public String? authorization{ get; set; }

[JsonPropertyName("operation_type")]
public String? operation_type{ get; set; }
}

public class FailureReportType
{
[JsonPropertyName("id")]
public String? failureReportId{ get; set; }

[JsonPropertyName("failureType")]
public String? failureReportType{ get; set; }
}
beautifulcoder
  • 10,832
  • 3
  • 19
  • 29
0

if you want to deserialize these jsons to your flatten class, you can create a JsonConstructor

public class TestClass
{
    public int id { get; set; }

    [JsonProperty("event_date")]
    public string? eventDate { get; set; }

    public String? type { get; set; }

    public String? transactionId { get; set; }

    public String? authorization { get; set; }

    public String? operationType { get; set; }

    public String? failureReportId { get; set; }

    public String? failureReportType { get; set; }

    [JsonConstructor]
    public TestClass(JToken transaction, JToken failureReport)
    {
        if (transaction != null)
        {
            transactionId = (string?)transaction["id"];
            authorization = (string?)transaction["authorization"];
            operationType = (string?)transaction["operation_type"];
        };
        if (failureReport != null)
        {
            failureReportId = (string?)failureReport["id"];
            failureReportType = (string?)failureReport["failureType"];
        };
    }

     public TestClass() { }
}

and since you are using Newtonsoft.Json for deserialization, you have to use [JsonProperty] instead of [JsonPropertyName]

Serge
  • 40,935
  • 4
  • 18
  • 45