0

I've raw JSON data that looks like this:

{
    "Pages": 0,
    "Page": null,
    "Rows": null,
    "OrderBy": null,
    "Desc": false,
    "TotalRows": 36,
    "HasError": false,
    "Error": null,
    "Result": {
        "fileTypes": [
            {
                "id": 22,
                "description": "Cleaning Procedures",
                "Codes": ""
            },
            {
                "id": 32,
                "description": "Data Drop",
                "Codes": "[\"DB\",\"IE\"]"
            },
            {
                "id": 4,
                "description": "Data Sheet",
                "Codes": ""
            },
            {
                "id": 30,
                "description": "Description of Operation",
                "Codes": ""
            },
            {
                "id": 11,
                "description": "Diagram",
                "Codes": ""
            },
            {
                "id": 2,
                "description": "Drawing",
                "Codes": "[\"DR\"]"
            }
        ]
    }
}

And a C# Model that looks like this:

public class Filetype
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("description")]
    public string Description { get; set; }
    [JsonProperty("Codes")]
    //public string Codes { get; set; }

    public List<string> Codes { get; set; }
}

However, Newtonsoft is not deserializing the codes into a list of codes but rather returning

[\"DB\",\"IE\"] in the first element of the list , or , "" , (null).

Any help with this would be appreciated.

LopDev
  • 823
  • 10
  • 26
M Leipper
  • 277
  • 5
  • 20
  • Use this to convert your json to a class set https://app.quicktype.io/ – Roman Ryzhiy Sep 24 '20 at 12:14
  • Copy your json string, then in VS: Edit -> Paste Special -> Paste JSON as Classes and use that type to deserialize your json. – SᴇM Sep 24 '20 at 12:15
  • Just to be Clear I already have the class files I'm having issues with RestSharp Deserializing the JSON Object in the expected fashion. – M Leipper Sep 24 '20 at 12:17
  • 2
    That isn't the correct expectation, though. `"Codes": "anything here"` is a string, not a collection of strings. So, NewtonSoft works as expected. Your input is rather suboptimal. – Fildor Sep 24 '20 at 12:18
  • 1
    Each value for `Codes` is enclosed in quotation marks, making it a string, not an array. `"Codes": "[\"DB\",\"IE\"]"` should be `"Codes": [\"DB\",\"IE\"]`. – Johnathan Barclay Sep 24 '20 at 12:19
  • Do you have some saying in how that input is formatted/created or do you have to deal with what you get? Answer heavily depends on this. If you do have a word, in all respect have that field fixed to actually be an array. If not, you may be able to fix it, but _meh_ ... you shouldn't if you can by any chance fix input. – Fildor Sep 24 '20 at 12:23
  • i've access to sever and client-side code I've no control over the DB which returns a string like ["DB", "IE"] – M Leipper Sep 24 '20 at 12:31
  • That look like a typo has Json is an object serialisation, there is no reason to do it by hands.. – Drag and Drop Sep 24 '20 at 12:33
  • 1
    Oh, in that case you have a JSON string _in_ the db. You need to fix server side, not client side... because: If you draw this out of db _as a string_ , set a model field to that string ( i.e. `model.Codes = stringFromDB;` ) and then serialize to json, you'll get exactly what you are seeing here. – Fildor Sep 24 '20 at 12:35
  • Ho if a property is a string representing an other json, Get a the value in a string property and have a property of the type of that inner object and deserialize the inner string if the property is null. There should be a know dupe on SO about "inner Json" or "json in json property". with the C# keyword – xdtTransform Sep 24 '20 at 12:38
  • Next time copy paste your json in VS to get classes or use online json2csharp tool that will give you valid classes. It this case you would get public string Codes { get; set; } as this is a string in JSON. – Leszek P Sep 24 '20 at 12:45
  • 1
    @LeszekP That really wouldn't help here. Issue can be fixed on both sides, but not with automated code generation. – Fildor Sep 24 '20 at 12:46
  • 1
    Indeed my comment was too short. It would not fix it, it was just a tip how to debug it next time. If I am excepting to get a List of strings, but the generated code is just a string then something is not correct and need investigating in Json/XML, etc. This was just a comment/tip not an answer, as there is already valid answer from @matmahnke. Cheers – Leszek P Sep 24 '20 at 12:50
  • @LeszekP Then it makes sense, yes. Same with having your model serialized and looking at the differences to what you would have expected... – Fildor Sep 24 '20 at 13:04

2 Answers2

3

code has de following value "["DB","IE"]" but list in json does not need quotes

the value of codes in json needs to be like this

 "Codes": ["DB","IE"]
matmahnke
  • 432
  • 3
  • 10
  • @MichaelLeipper OK, that out of the way: You can _fix_ this on both sides. Which one would you prefer? On Server or Client? – Fildor Sep 24 '20 at 12:45
1

Client Side :

If one of the property is a string serialisation of a Json.
You can add a Property with [JsonIgnore] that represent the result of the deserialisation :

public class Foo{
    public string BarsInString {get;set;}       
    [JsonIgnore]
    public Bar[] Bars 
    {
        get 
         {
            return JsonConvert.DeserializeObject<Bar[]>(UserInput);
         }
       set 
        {
           BarsInString = JsonConvert.SerializeObject(value);
        }     
    }
}

Live Demo: https://dotnetfiddle.net/l5JWVb

I chooseed something bigger than an List<string> to illustrate. In your case it will boils down to:

public class Filetype
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("description")]
    public string Description { get; set; }
    [JsonProperty("Codes")]
    public string CodesInJson { get; set; }

    [JsonIgnore]
    public List<string> Codes {
        get 
         {
            return JsonConvert.DeserializeObject<List<string>>(CodesInJson);
         }
       set 
        {
           CodesInJson = JsonConvert.SerializeObject(value);
        }     
    }
}

Server Side:

If one of the property is a Json serialisation of something else you may want to deserialise it before sending it. Using the same kind of code:

JsonConvert.DeserializeObject<List<string>>(myJsonFromDb);
xdtTransform
  • 1,986
  • 14
  • 34
  • 2
    Maybe it's worth adding, that you can fix this also **at the server**, by deserializing the json string from db to a List in the model, which then is serialized to json again. Some db-Drivers can do that for you if you tell them which columns are actually json. (Depends on DB and driver) – Fildor Sep 24 '20 at 13:02
  • 2
    Tryed my best to make it into something intelligible. I didn't add the part about db-Drivers, because I simply didn't knew about it. You can edit the answer if you want to add something. – xdtTransform Sep 24 '20 at 14:42