I am trying to deserialize a JSON string from an API response but I am getting the following error:
Unable to find a constructor to use for type
Microsoft.AspNetCore.Mvc.FileContentResult. A class should either have
a default constructor, one constructor with arguments or a constructor
marked with the JsonConstructor attribute. Path ‘file.fileContents’,
line 1, position 24.
This is the code that my API controller is running and returning:
var fileName = string.Format("invoice_{0}.pdf", body.InvoiceNumber);
var content = result.InvoiceStream.ToArray();
FileContentResult file = new FileContentResult(content, "application/pdf");
file.FileDownloadName = fileName;
return new CreatePreviousInvoiceResponse
{
File = file
};
This is my class for storing the file:
public class CreatePreviousInvoiceResponse
{
public FileContentResult? File { get; set; }
public string? Error { get; set; }
[JsonConstructor]
public CreatePreviousInvoiceResponse()
{
}
}
And this is where I deserialize the response (shortened for brevity):
string body = JsonConvert.SerializeObject(cbody);
try
{
HttpContent cont = new StringContent(body, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _client.PostAsync(uri, cont);
string content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<CreatePreviousInvoiceResponse>(content);
}
catch (Exception ex)
{
return new CreatePreviousInvoiceResponse
{
Error = ex.Message
};
}
The exception occurs on the DeserializeObject
line from above. As you can see I added a default constructor with a JSonConstructor
tag in my CreatePreviousInvoiceResponse
class, so I’m not sure why the error is still occurring.
I receive a 200 response from my Post call, and the content
string is also populated just fine with the below contents:
{"file":{"fileContents":"","contentType":"application/pdf","fileDownloadName":"invoice_2023-44.pdf","lastModified":null,"entityTag":null,"enableRangeProcessing":false},"error":null}
2
Answers
So I misunderstood the problematic class. It's not my FileContentResult class but the FileContentResult.
In the end I just altered my CreatePreviousInvoiceResponse class to return the byte array only, and in my page codebehind I reconstructed constructed the FileContentResult.
I have no idea why it couldn't deserialize FileContentResult.
With the search on the Internet, the FileContentResult class in .NET is not designed for JSON serialization or deserialization. It is intended for use within the MVC framework to write binary files to the response. The class lacks a default constructor and properties suitable for typical JSON structures, which likely causes the deserialization issue. You could use an alternative approaches, such as modifying the response to include a byte array or a file path/URL, which are more compatible with JSON serialization and deserialization processes.
For instance: