skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.


  2. 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:

    public class CreatePreviousInvoiceResponse
    {
        public byte[] FileData { get; set; }
        public string FileName { get; set; }
        public string ContentType { get; set; }
    
        // Constructor and other necessary methods
    }
    
    // In your API method
    public CreatePreviousInvoiceResponse GetInvoice(int id)
    {
        // Load your file data
        byte[] fileData = ...; // Your logic to get the file data
        string fileName = "invoice.pdf"; // Example file name
        string contentType = "application/pdf"; // Example content type
    
        return new CreatePreviousInvoiceResponse
        {
            FileData = fileData,
            FileName = fileName,
            ContentType = contentType
        };
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search