0

I have a json file with the following content:

{
    "Id": 0,
    "Name": "todoList1",
    "ListItems": [
        {
            "Id": 1,
            "Description": "listItem1.1",
            "Done": false
        },
        {
            "Id": 2,
            "Description": "listItem1.2",
            "Done": true
        }
    ]
}

Additionally I have an ASP.NET Core 3.1 API method which should be able to partially update the json:

 [HttpPatch("{name}")]
    public async Task<TodoListDomainModel> Update([FromRoute] string name, [FromBody]JsonPatchDocument<TodoListDomainModel> todoListJsonPatchDocument)
    {
        var todoListToPatch = (await this._todoListService.GetTodoLists()).Single(x => x.Name == name);
        todoListJsonPatchDocument.ApplyTo(todoListToPatch);
        return todoListToPatch;
    }

The TodoListDomainModel:

public class TodoListDomainModel
{
    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<ListItemDomainModel> ListItems { get; set; } = new Collection<ListItemDomainModel>();
}

The ListItemDomainModel:

public class ListItemDomainModel
{
    public ListItemDomainModel()
    {
    }

    public int Id { get; set;  }

    public string Description { get; set; }

    public bool Done { get; set; }

    public DateTime DueDate { get; set; }
}

Calling the API method via Angular

When calling the API method via angular:

save(selectedTodoList: TodoList) {
    let test = JSON.stringify(selectedTodoList.listItems);
    let json = `[{"op": "replace", "path": "/ListItems", "value": ${test} }]`;
    let url = `https://localhost:44305/todolist/${selectedTodoList.name}`;
    return this.http.patch<TodoList>(url, json);
  }

I'm not even coming to the breakpoint in the api method.

Is there something I'm doing wrong?

Thanks in advance

xeraphim
  • 4,375
  • 9
  • 54
  • 102
  • bad way to compose the JSON body: the string could result malformed (and that's the supect about your trouble). Build the JSON as a JavaScript object, and deliver it as is. – Mario Vernari Aug 03 '20 at 07:40
  • What do you mean with building the JSON as a JS object? sorry, I'm new to the frontend stuff :) – xeraphim Aug 03 '20 at 07:45
  • What is your `TodoListDomainModel` in controller? – Yiyi You Aug 03 '20 at 07:46
  • @YiyiYou: The TodoListDomainModel looks like this: public class TodoListDomainModel { public int Id { get; set; } public string Name { get; set; } public ICollection ListItems { get; set; } = new Collection(); } – xeraphim Aug 03 '20 at 07:48
  • @xeraphim look at my answer below – Mario Vernari Aug 03 '20 at 07:49

1 Answers1

2

Try to compose the JSON body as JavaScript object:

save(selectedTodoList: TodoList) {
    const body = [{
        op: "replace",
        path: "/ListItems",
        value: selectedTodoList.listItems
    }];
    let url = `https://localhost:44305/todolist/${selectedTodoList.name}`;
    return this.http.patch<TodoList>(url, body);
}
xeraphim
  • 4,375
  • 9
  • 54
  • 102
Mario Vernari
  • 6,649
  • 1
  • 32
  • 44
  • I've added a `.subscribe()` at the end of the `http.patch`. Unfortunately, I now get the following error: `error: Object { type: "https://tools.ietf.org/html/rfc7231#section-6.5.1", title: "One or more validation errors occurred.", status: 400, … }`. How is this possible? I don't even have any validations :) – xeraphim Aug 03 '20 at 07:51
  • It says `The JSON patch document was malformed and could not be parsed` it seems like there is still something wrong with creating the body this way :( – xeraphim Aug 03 '20 at 07:54
  • yes, but that's a good sign: it means that the JSON is sent and arrives to the backend. Now the problem is that the C# class does not match the incoming JSON. – Mario Vernari Aug 03 '20 at 07:55
  • use the browser dev-tools (F12 for Chrome), and analyze what's the actual body flowing through the HTTP patch request. – Mario Vernari Aug 03 '20 at 07:59
  • This is the json that gets sent: `{"op":"replace","path":"/ListItems","value":[{"id":1,"description":"listItem1.1","done":false,"dueDate":"0001-10-08T23:25:52.000Z"},{"id":2,"description":"listItem1.2","done":true,"dueDate":"0001-01-01T00:00:00"}]}` from the dev-tools – xeraphim Aug 03 '20 at 08:00
  • I think there is an `[ ]` missing around everything. When I use PostMan with the request without the `[]` I get the same malformed exception, but when I add `[]` around everything it works. How can I get that in the request? – xeraphim Aug 03 '20 at 08:03
  • 1
    well, yes. I didn't know what `JsonPatchDocument` is, but it seems a wrapper around a collection, thus an array is likely the right object to send. Notice that I've wrapped the `body` constant with the square braces. – Mario Vernari Aug 03 '20 at 08:11
  • It works like this: `const body: Array<{op: string, path: string, value: any}> = [{ op: "replace", path: "/ListItems", value: selectedTodoList.listItems }];` Maybe you can add it to your answer for future people having the same problem :) thanks for your help! – xeraphim Aug 03 '20 at 08:14