0

How can i download csv file without ending The Action by using return Command?

I want to have an action that can download a csv file and continue with action logic. is it possible to initiate a request without actually end the action and return back from the controller? something like that :

public IActionResult AddOrdersExtension(OrderVM orderVM)
{
  if (ModelState.IsValid)
     {
        StringBuilder sb = new StringBuilder();
         //Header             
     sb.Append("Product,Empty,Name,Address1,Address2,City,State,zip,Country,Phone,Quantity,Weight");
                FileContentResult fr = File(Encoding.ASCII.GetBytes(sb.ToString()), "text/csv", 
      "Error_log.csv");
//
//execute csv download
//
// continue with function

return View(orderVM.Orders); // return from action when logic is done
}//end function
Kobi
  • 89
  • 7
  • I'm not sure, what you mean with download and logic after, but it seems you want to return FileContent and a View with one Request, am I right? – Nikolaus Nov 28 '20 at 15:40
  • yes, the action is processing orders, if there was at least 1 failed order i want to create error log csv file to the user. But also want to go back to the View and show a sweet alert message – Kobi Nov 28 '20 at 15:46
  • Anyone? Still stuck :) – Kobi Nov 29 '20 at 12:40
  • 1
    The same request cannot respond to `FileContent` and` View` at the same time. One solution is to save the generated csv file in a certain place. Then pass a link to the view data to download. – Karney. Nov 30 '20 at 06:41
  • Another Possibility is to integrate the csv in the Response. – Nikolaus Nov 30 '20 at 07:15
  • @Nikolaus If i send the FileContentResult With the response, How can i download the file to the user in the View ? – Kobi Dec 01 '20 at 17:13
  • @Kobi you can do it clientside in JavaScript: [like this](https://stackoverflow.com/questions/14964035/how-to-export-javascript-array-info-to-csv-on-client-side) – Nikolaus Dec 01 '20 at 23:44

1 Answers1

0

From your codes, the following is an in-memory operation:

FileContentResult fr = File(Encoding.ASCII.GetBytes(sb.ToString()), "text/csv", 
      "Error_log.csv");

Do download the file from the server again you need to store the file. Not sure why you want to download the file here! But if you want you can save the file to a temporary folder, download and then remove the file like this:

FileContentResult fr = File(Encoding.ASCII.GetBytes(sb.ToString()), "text/csv", "Error_log.csv");

//For concurrent access use dynamic name file names

//Save to disk

File.WriteAllBytes( "~/tmp/Error_log.csv", ((FileContentResult)fr).FileContents);

//Download

string remoteUri = "http://www.yourdomain.com/tmp/";
string fileName = "Error_log.csv_downloaded", myStringWebResource = null;

// Create a new WebClient instance and download the file

using (WebClient myWebClient = new WebClient())
{
    myStringWebResource = remoteUri + fileName;
    // Download the Web resource and save it into the current filesystem folder.
    myWebClient.DownloadFile(myStringWebResource, fileName);        
}

//Delete both the files

var fullPath = Server.MapPath("~/tmp/Error_log.csv");

        if (File.Exists(fullPath))
        {
            File.Delete(fullPath);
        }

fullPath = Server.MapPath("~/tmp/Error_log.csv_downloaded");

        if (File.Exists(fullPath))
        {
            File.Delete(fullPath);
        }

There might be some syntax errors and reference libraries to be added. But I hope you get the solution you are looking for.

Rahatur
  • 2,444
  • 3
  • 29
  • 39