Unable to cast object of type Newtonsoft.Json.Linq

2020-02-15 04:33发布

问题:

I am working with ASP.NET Core 2.0 in VS2017.

I am trying to deserialize some JSON that is returned in an HttpResponseMessage but I am getting an "Unable to cast object of type..." exception.

Here is the code that is failing;

FilesUploadedListResponse fileUploadListResponse = new FilesUploadedListResponse();
string jsonResult = response.Content.ReadAsStringAsync().Result;
fileUploadListResponse = (FilesUploadedListResponse)JsonConvert.DeserializeObject(jsonResult);

The last line is where I get the exception...

"Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'FilesUploadedListResponse'."

Here is the actual Json that is in the string jsonResult:

"{\"uploadedfiles\":[],\"totalResults\":0,\"pageNumber\":0,\"pageSize\":0}"

The uploadedFiles array is empty in this result, because there are no uploaded files yet, but I would think that having it empty shouldn't create an exception, should it? If it were not empty, it would have a response similar to this:

{
 "uploadedFiles": [
 {
 "id": 1,
 "createdTime": "July 10, 2017 02:02:25 PM",
 "filename": "20170710_14022507701.jpg",
 "sentTime": "July 10, 2017 02:05:11 PM",
 "fileSize": "124 KB"
 },
 {
 "id": 2,
 "createdTime": "June 05, 2017 09:39:25 AM",
 "filename": "20170605_093907701.jpg",
 "sentTime": "June 05, 2017 09:40:11 AM",
 "fileSize": "1 MB"
 }
],
 "totalResults": 2,
 "pageNumber": 0,
 "pageSize": 2
}

Here is my FileUploadListResponse class:

public class FilesUploadedListResponse
{
    public bool Success { get; set; }
    public string Reason { get; set; }
    public int StatusCode { get; set; }
    public List<UploadedFile> UploadedFiles { get; set; }
    public int TotalResults { get; set; }
    public int PageNumber { get; set; }
    public int PageSize { get; set; }
}

And here is my UploadedFile class:

public class UploadedFile
{
    public int Id { get; set; }
    public DateTime CreatedTime { get; set; }
    public string Filename { get; set; }
    public DateTime? SentTime { get; set; }
    public string FileSize { get; set; }
}

My understanding of the JSON deserialization is that:

  1. The case of the elements doesn't matter between the values in the JSON string and the class object I am trying to deserialize to.

  2. The class I am trying to deserialize to can have more properties that what is provided in the JSON string, just as long as the properties that are in the JSON string are accounted for.

  3. An empty sub array, such as the UploadedFiles array should not cause an error when trying to deserialize to the List<UploadedFile>

I am sure it is something simple, but I am just not seeing it. What am I missing here?

回答1:

When you call the non-generic method JsonConvert.DeserializeObject(jsonResult), you are asking Json.NET to deserialize the incoming JSON into some .Net type of its own choosing that is sufficient to capture the incoming JSON. What it in fact chooses is a LINQ to JSON JObject. Since this type is not implicitly or explicitly convertible to your FilesUploadedListResponse type, you get the exception you see.

Since want to deserialize to a specific, known type, you should instead call the generic method JsonConvert.DeserializeObject<FilesUploadedListResponse>(jso‌​nResult) which Deserializes the JSON to the specified .NET type like so:

string jsonResult = response.Content.ReadAsStringAsync().Result;
var fileUploadListResponse = JsonConvert.DeserializeObject<FilesUploadedListResponse>(jsonResult);