so I'm in process of migrating of my app from .NET Framework 4.8 to .NET6. Due to some .NET classes being obsolete in newer version I am experiencing some problems.
I have a controller in which one of endpoints is supposed to return a PDF file. But instead of this what it returns right now is just a JSON file containing only a few values.
Endpoint method:
[HttpPost]
public ActionResult DownloadFile([FromForm] string data, [FromForm] string fileType)
{
try
{
if (!string.IsNullOrWhiteSpace(data))
{
return GenerateReportDocument(data, fileType);
}
}
catch (Exception ex)
{
logger.LogError(ex, $"Unexpected error occured in {nameof(DownloadFile)}.");
return StatusCode(500);
}
return NoContent();
}
Then data is taken into GenerateReportDocument method:
private ActionResult GenerateReportDocument(string data, string fileType)
{
var specificationString = specificationGeneratorService.GenerateSpecificationString(JObject.Parse(data));
logger.LogWarning($"Check images in specificationString: '{specificationString}'");
if (string.IsNullOrWhiteSpace(specificationString))
{
specificationString = "<p></p>";
}
var reportGenerator = generateReportDocuments.SingleOrDefault(r => r.FileType.ToLower().Equals(fileType.ToLower()));
if (reportGenerator is not null)
{
return Ok(reportGenerator.GenerateReportDocument(SpecificationFileName, specificationString));
}
return NoContent();
}
Which then is supposed to be taken into third method:
public HttpContent GenerateReportDocument(string fileName, string specificationString)
{
var requestContent = new StringContent(JsonConvert.SerializeObject(new { Html = specificationString }));
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpResponse = Flurl.Url.Combine(_abcPdfOptions.PdfConverterUrl, "pdf/convertfromhtmltopdf")
.PostAsync(requestContent).GetAwaiter().GetResult();
HttpContent httpContent = httpResponse.Content;
httpContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = $"{fileName}.{FileExt}",
};
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return httpContent;
}
This is how those methods looked like in .NET Framework 4.8 (when they were working correctly, presented in same order as their equivalent methods in .NET6 project):
[HttpPost]
public HttpResponseMessage DownloadFile(HttpRequestMessage requestMessage)
{
try
{
var specification = requestMessage.Content.ReadAsFormDataAsync().Result;
string data = specification.Get("Data");
string fileType = specification.Get("FileType");
if (!string.IsNullOrWhiteSpace(data))
{
return GenerateReportDocument(data, fileType);
}
}
catch (Exception ex)
{
logger.LogError(ex, $"Unexpected error occured in {nameof(DownloadFile)}.");
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
private HttpResponseMessage GenerateReportDocument(string data, string fileType)
{
var specificationString = specificationGeneratorService.GenerateSpecificationString(JObject.Parse(data));
logger.LogWarning($"Check images in specificationString: '{specificationString}'");
if (string.IsNullOrWhiteSpace(specificationString))
{
specificationString = "<p></p>";
}
var reportGenerator = generateReportDocuments.SingleOrDefault(r => r.FileType.ToLower().Equals(fileType.ToLower()));
if (reportGenerator != null)
{
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = reportGenerator.GenerateReportDocument(SpecificationFileName, specificationString),
};
}
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
public HttpContent GenerateReportDocument(string fileName, string specificationString)
{
var requestContent = new StringContent(JsonConvert.SerializeObject(new { Html = specificationString }));
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpResponse = Flurl.Url.Combine(_abcPdfOptions.PdfConverterUrl, "pdf/convertfromhtmltopdf")
.PostAsync(requestContent).GetAwaiter().GetResult();
HttpContent httpContent = httpResponse.Content;
httpContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = $"{fileName}.{FileExt}",
};
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return httpContent;
}
I have tried editing my code and changing the methods into IActionResult or HttpResponse, also altering the return types and their arguments. What am I doing wrong? Is ActionResult a good choice for what I'm trying to do?
CodePudding user response:
Did you try returning FileStreamResult/File ?
var fileStream = new FileStream(@"file_path", FileMode.Open);
return new FileStreamResult(fileStream, "application/pdf");
Or
var fileStream = new FileStream(@"file_path", FileMode.Open);
return File(fileStream , "application/pdf", "FileDownloadName.ext");
CodePudding user response:
if you are doing an ajax call to the controller, then no file will be downloaded, you will receive some json data.you need to make a non ajax call so that server will download the file