Home > Software design >  ActionResult not returning a PDF file
ActionResult not returning a PDF file

Time:08-05

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

  • Related