Home > Software design >  how does C# class look like to match this JSON
how does C# class look like to match this JSON

Time:10-30

I have this JSON string that should be posted from JavaScript to the API:

  "model": "kpi.availability",
  "typeId": "kpi.availability",
  "name": "Availability",
  "description": "",
  "version": "1.0.0",
  "properties": {
    "X": {
      "dataType": "string",
      "value": ""
    },
    "Y": {
      "dataType": "number",
      "value": 0,
      "isMandatory": true
    },
    "Z": {
      "dataType": "number",
      "value": 0,
      "isMandatory": true
    }
  }

here we have 3 properties, just for instance, but it can be more than 3 with different names.

And have this C# model which doesn't work

public class KPIType{
public string   model  { get; set; }  
public string typeId { get; set; }
public string name { get; set; }
public string description { get; set; }
public int version { get; set; }
public IDictionary<string, PropertyItem>[] properties  { get; set; }
//public List<IDictionary<string, PropertyItem>> properties  { get; set; } //Didn't work
  }

  public class PropertyItem {
    public string dataType { get; set; }
    public string value { get; set; }
    public bool isMandatory { get; set; }
  }

But when trying to send it to the backend, it fails at the client side and I'm getting this error:

"The JSON value could not be converted to System.Collections.Generic.IDictionary`2[System.String,ABB.Advanced.Services.Management.Controllers.PropertyItem][]. Path: $.kpiType.properties | LineNumber: 0 | BytePositionInLine: 294."

enter image description here

CodePudding user response:

This JSON is incorrect in array section. It should be like this:

{
  "model": "kpi.availability",
  "typeId": "kpi.availability",
  "name": "Availability",
  "description": "",
  "version": "1.0.0",
  "properties": [
    {
      "dataType": "string",
      "value": "",
      "isMandatory": true
    },
    {
      "dataType": "number",
      "value": 0,
      "isMandatory": true
    },
    {
      "dataType": "number",
      "value": 0,
      "isMandatory": true
    }
  ]
}

If you want to pass objects with names into property array then you need to add "name" property to the object and then find it in your service by the name.

Exempli gratia:

  "properties": [
    {
      "name": "A",
      "dataType": "string",
      "value": "",
      "isMandatory": true
    },
    {
      "name": "B",
      "dataType": "number",
      "value": 0,
      "isMandatory": true
    },
    {
      "name": "C",
      "dataType": "number",
      "value": 0,
      "isMandatory": true
    }
  ]

CodePudding user response:

Two things are obvious mismatch:

  • Properties in C# is array, but in JSON file it is an object. Not sure what's the best to fix it, maybe best change the JSON file itself, if possible
  • isMandatory is bool, that is, required. However, in X it is missing. If it is optional - change it to bool?

CodePudding user response:

Just remove the "[]" in front of the field "properties":

I mean use this:

 public IDictionary<string, PropertyItem>[] properties  { get; set; }

Replace it with:

public IDictionary<string, PropertyItem> Properties  { get; set; }

I highly recommend you use a better naming convention on your class fields according to the Microsoft official docs

NOTE: If your JSON deserialization is case sensitive you can use the [JsonProperty] attribute on your props like this:

[JsonProperty("properties")
public IDictionary<string, PropertyItem> Properties  { get; set; }

public class PropertyItem
{
    [JsonProperty("dataType")]
    public string DataType { get; set; }

    [JsonProperty("value")]
    public string Value { get; set; }

    [JsonProperty("isMandatory")]
    public bool IsMandatory { get; set; }
}
  • Related