I am working on mechanism to export data in CSV format.
I am sending data in JSON
format using jQuery :
var data = JSON.stringify(dataToSend);
$.post('DumpToCSV', { 'data': data });
Then in the controller I am generating a CSV file :
public ActionResult DumpToCSV(string data)
{
Response.Clear();
XmlNode xml = JsonConvert.DeserializeXmlNode("{records:{record:" + data + "}}");
XmlDocument xmldoc = new XmlDocument();
//Create XmlDoc Object
xmldoc.LoadXml(xml.InnerXml);
//Create XML Steam
var xmlReader = new XmlNodeReader(xmldoc);
DataSet dataSet = new DataSet();
//Load Dataset with Xml
dataSet.ReadXml(xmlReader);
//return single table inside of dataset
var csv = CustomReportBusinessModel.ToCSV(dataSet.Tables[0], ",");
HttpContext context = System.Web.HttpContext.Current;
context.Response.Write(csv);
context.Response.ContentType = "text/csv";
context.Response.AddHeader("Content-Disposition", "attachment;filename=Custom Report.csv");
Response.End();
return null;
}
It returns back the CSV in response, but how do I tell the browser to donwload it?
The difference between this topic : Returning a file to View/Download in ASP.NET MVC Is that I'm using AJAX request
If you want to download file based on some data that you can post to Controller it's better not use Ajax, becouse it's really hard to deal with files via Ajax. One of posible solutions is to add link to additional library.
What i whould like to advice you is to use simple GET request:
In your javaScript
code:
var urlParams = $.param(dataToSend);
window.location.href = "DumpToCSV"+ urlParams;
This way you serialize all your data to url string and have no problem with getting file via Ajax.
Then in your Controller
it's better to return FileContentResult
or even FileStreamResult
if you have really big files. Also, your model that go into yout controller can be strongly typed and MVC ModelBuilder
Map it from url string easily. So yout data object can be c# class like this:
public class CSVData
{
public string Name { get; set; }
public int Count { get; set; }
public int SomeId { get; set; }
}
And you don't need to desirialize your data in Controller at all. See more info here.
public FileContentResult DumpToCSV(CSVData data)
{
XmlNode xml = data.ToXmlNode();
XmlDocument xmldoc = new XmlDocument();
//Create XmlDoc Object
xmldoc.LoadXml(xml.InnerXml);
//Create XML Steam
var xmlReader = new XmlNodeReader(xmldoc);
DataSet dataSet = new DataSet();
//Load Dataset with Xml
dataSet.ReadXml(xmlReader);
//return single table inside of dataset
var csv = CustomReportBusinessModel.ToCSV(dataSet.Tables[0], ",");
return File(new System.Text.UTF8Encoding().GetBytes(csv), "text/csv", "Custom Report.csv");
}
As you can see the is no need to work with HttpContext
in MVC in your case you can do it much cleanier and obvious way.
PS. If your csv
object is just a byte[]
then you can write like this:
return File(csv, "text/csv", "Custom Report.csv");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With