wp-net / WordPressPCL

This is a portable library for consuimg the WordPress REST-API in (almost) any C# application
MIT License
338 stars 129 forks source link

CustomRequest.Create throws 'Cannot deserialize the current JSON array' exception #170

Closed hbcondo closed 5 years ago

hbcondo commented 5 years ago

When calling the CustomRequest.Create method, the following exception is thrown:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'BPGroup' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\nPath '', line 1, position 1.

Below is the code snippet that is experiencing this issue:

try
{
    var group = client.CustomRequest.Create<BPGroup, BPGroup>("buddypress/v1/groups", new BPGroup() { name = name, slug = slug, description = desc, creator_id = 1 }).Result;
}
catch (Exception ex)
{
    Console.Error.Write("This is where the exception occurs");
}

public class BPGroup
{
    public string name;
    public string slug;
    public string description;
    public int creator_id;
}

HTTP Request:

POST https://domain.local/wp-json/buddypress/v1/groups HTTP/1.1
Authorization: Bearer [key]
Content-Type: application/json; charset=utf-8
Host: [domain]
Cookie: PHPSESSID=[value]
Content-Length: 177

{"name":"my name","slug":"my slug","description":"my desc","creator_id":1}

HTTP Response:

[
  {
    "id": 11,
    "creator_id": 2,
    "parent_id": 0,
    "date_created": "2019-04-03T23:08:07",
    "description": {
      "rendered": "<p>my desc</p>\n"
    },
    "enable_forum": false,
    "link": "my link",
    "name": "my name",
    "slug": "my slug",
    "status": "public",
    "avatar_urls": {
      "thumb": "https://domain.local/wp-content/plugins/buddypress/bp-core/images/mystery-group-50.png",
      "full": "https://domain.local/wp-content/plugins/buddypress/bp-core/images/mystery-group.png"
    },
    "_links": {
      "self": [
        {
          "href": "https://domain.local/wp-json/buddypress/v1/groups/11"
        }
      ],
      "collection": [
        {
          "href": "https://domain.local/wp-json/buddypress/v1/groups/"
        }
      ],
      "user": [
        {
          "embeddable": true,
          "href": "https://domain.local/wp-json/buddypress/v1/members/2"
        }
      ]
    }
  }
]
polushinmk commented 5 years ago

@hbcondo seems that responce type is not simple BPGroup but an array of BPGroup. Trt to change return type like this

var group = client.CustomRequest.Create<BPGroup, BPGroup[]>("buddypress/v1/groups", new BPGroup() { name = name, slug = slug, description = desc, creator_id = 1 }).Result;
hbcondo commented 5 years ago

@polushinmk, thank you for your reply. I think your suggestion worked in that the JSON serialization exception isn't being thrown using the array return type but a new exception is being thrown:

Unexpected character encountered while parsing value: {. Path '[0].description', line 1, position 93.

I guess the description property in the response is causing this since it's a json object and WordPressPCL / Newtonsoft isn't expecting this type? If so, any suggestions on how to handle it? Thanks again.

image

polushinmk commented 5 years ago

@hbcondo you are right, this is an object instead of string. For this case you can create separate object for output. So you will have 2 objects: BPGroupInput and BPGroupOutput (for example)

client.CustomRequest.Create<BPGroupInput, BPGroupOutput[]>

description is a simple object with 1 property named "rendered"

class Description {
    string rendered {get;set;}
}
hbcondo commented 5 years ago

Great, this approach worked; thanks again for reviewing and providing code snippets. I'm closing this issue, the exceptions experienced were not specific to WordPressPCL or Newtonsoft.