Home > Back-end >  Turning multiple json string of same type into List<T> C#
Turning multiple json string of same type into List<T> C#

Time:11-24

Hey im working on a litle project right now and i need to turn a list of json string into List<TaskStruct.cs> I have included all the needed code if something is missing let me know!

im getting the json with flurl if that helps

The important bits:

This should get the list from my api:

public async static Task<List<TaskStruct>> GetTasks()
{
    return await $"{BASE}tasks/".GetJsonAsync<List<TaskStruct>>();
}

This is the response from the api:


    [
        "{\"id\": \"1\", \"date\": \"25.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
        "{\"id\": \"2\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
        "{\"id\": \"10362\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
        "{\"id\": \"23726\", \"date\": \"25.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
        "{\"id\": \"41445\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"TODO\\r\\n\\r\\n\\r\\nmehr\\r\\n\\r\\n222\\r\\n312\\r\\n312\\r\\n\", \"done\": false}",
        "{\"id\": \"49761\", \"date\": \"23.11.2022\", \"start\": \"Start\", \"end\": \"Ende\", \"betrag\": \"Betrag\", \"todo\": \"TODO\", \"done\": false}",
        "{\"id\": \"53618\", \"date\": \"23.11.2022\", \"start\": \"Start\", \"end\": \"Ende\", \"betrag\": \"Betrag\", \"todo\": \"TODO\", \"done\": false}",
        "{\"id\": \"54019\", \"date\": \"25.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
        "{\"id\": \"87156\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}"
    ]

This is the TaskStruct.cs

public struct TaskStruct
{
    public string date { get; set; }
    public string start { get; set; }
    public string end { get; set; }
    public string betrag { get; set; }
    public string todo { get; set; }
    public bool done { get; set; }

    public TaskStruct(string date, string start, string end, string betrag, string todo, bool done)
    {
        this.date = date;
        this.start = start;
        this.end = end;
        this.betrag = betrag;
        this.todo = todo;
        this.done = done;
    }
}

I then try todo this:


    private async void ShowTasks()
    {
        foreach (TaskStruct task in await TaskApi.GetTasks())
        {
            MessageBox.Show(task.todo);
        }
    }

But i get a : System.Reflection.TargetInvocationException: "Exception has been thrown by the target of an invocation." After a few seconds.

This is the stacktrace:

   bei Flurl.Http.FlurlRequest.<HandleExceptionAsync>d__35.MoveNext()
   bei Flurl.Http.FlurlResponse.<GetJsonAsync>d__18`1.MoveNext()
   bei Flurl.Http.ResponseExtensions.<ReceiveJson>d__0`1.MoveNext()
   bei AufgabenNet.TaskApi.<GetTasks>d__2.MoveNext() in C:\Users\justu\source\repos\AufgabenNet\AufgabenNet\TaskApi.cs: Zeile26
   bei AufgabenNet.AufgabenNet.<ShowTasks>d__1.MoveNext() in C:\Users\justu\source\repos\AufgabenNet\AufgabenNet\Form1.cs: Zeile13

This is the inner exception:

InnerException  {"Could not cast or convert from System.String to AufgabenNet.TaskStruct."} System.Exception {System.ArgumentException}

this is the message:

Message "Response could not be deserialized to JSON: GET http://127.0.0.1:5000/tasks/"  string

Which is weird since it looks like valid json

It get the Error on:

return await $"{BASE}tasks/".GetJsonAsync<List<TaskStruct>>();

CodePudding user response:

I think you should drop foreach(var task in tasks) and just deserialise to List<TaskStruct>:

public async Task<List<TaskStruct>> GetTasks()
{
    var json = await GetJsonAsync(); // try/catch maybe? 
    if(string.IsNullOrEmpty(json) 
    {
       ...
    }
    try 
    {
        var l = JsonConvert.DeserializeObject<List<TaskStruct>>(json)
        return l; 
    }
    catch(...)       
    { 
       ...
    }
}

CodePudding user response:

Since your JSON response is:

[
    "{\"id\": \"1\", \"date\": \"25.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
    "{\"id\": \"2\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
    "{\"id\": \"10362\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
    "{\"id\": \"23726\", \"date\": \"25.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
    "{\"id\": \"41445\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"TODO\\r\\n\\r\\n\\r\\nmehr\\r\\n\\r\\n222\\r\\n312\\r\\n312\\r\\n\", \"done\": false}",
    "{\"id\": \"49761\", \"date\": \"23.11.2022\", \"start\": \"Start\", \"end\": \"Ende\", \"betrag\": \"Betrag\", \"todo\": \"TODO\", \"done\": false}",
    "{\"id\": \"53618\", \"date\": \"23.11.2022\", \"start\": \"Start\", \"end\": \"Ende\", \"betrag\": \"Betrag\", \"todo\": \"TODO\", \"done\": false}",
    "{\"id\": \"54019\", \"date\": \"25.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}",
    "{\"id\": \"87156\", \"date\": \"26.11.2022\", \"start\": \"10:00\", \"end\": \"13:00\", \"betrag\": \"15\\u20ac\", \"todo\": \"awdawd awd awd awd awd awd aw awa   adw\", \"done\": true}"
]

You are actually getting an array of strings. In its current state, you'll have to deserialize it as a string array and loop over it. Something like so:

var taskStringList = await $"{BASE}tasks/".GetJsonAsync<string[]>();
var taskList = taskStringList.Select(s => JsonConvert.DeserializeObject<TaskStruct>(s)).ToList();

On the other hand, it would probably deserialize as expected if your JSON was as follows:

[
    {"id": "1", "date": "25.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "awdawd awd awd awd awd awd aw awa   adw", "done": true},
    {"id": "2", "date": "26.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "awdawd awd awd awd awd awd aw awa   adw", "done": true},
    {"id": "10362", "date": "26.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "awdawd awd awd awd awd awd aw awa   adw", "done": true},
    {"id": "23726", "date": "25.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "awdawd awd awd awd awd awd aw awa   adw", "done": true},
    {"id": "41445", "date": "26.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "TODO\\r\\n\\r\\n\\r\\nmehr\\r\\n\\r\\n222\\r\\n312\\r\\n312\\r\\n", "done": false},
    {"id": "49761", "date": "23.11.2022", "start": "Start", "end": "Ende", "betrag": "Betrag", "todo": "TODO", "done": false},
    {"id": "53618", "date": "23.11.2022", "start": "Start", "end": "Ende", "betrag": "Betrag", "todo": "TODO", "done": false},
    {"id": "54019", "date": "25.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "awdawd awd awd awd awd awd aw awa   adw", "done": true},
    {"id": "87156", "date": "26.11.2022", "start": "10:00", "end": "13:00", "betrag": "15\\u20ac", "todo": "awdawd awd awd awd awd awd aw awa   adw", "done": true}
]
  • Related