使用ASP .NET MVC和jQuery AJAX请求下载服务器生成的CSV

我正在研究以CSV格式导出数据的机制。 我使用jQueryJSON格式发送数据:

 var data = JSON.stringify(dataToSend); $.post('DumpToCSV', { 'data': data }); 

然后在控制器中我生成一个CSV文件:

  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; } 

它返回CSV作为响应,但我如何告诉浏览器下载它?

此主题之间的区别: 将文件返回到ASP.NET MVC中的查看/下载是我正在使用AJAX请求

如果你想根据你可以发布到Controller的一些数据下载文件,最好不要使用Ajax,因为通过Ajax处理文件真的很难。 一个可行的解决方案是添加到其他库的链接 。

我想建议你的是使用简单的GET请求:

在您的javaScript代码中:

 var urlParams = $.param(dataToSend); window.location.href = "DumpToCSV"+ urlParams; 

这样,您将所有数据序列化为url字符串,并且通过Ajax获取文件没有问题。

然后在你的Controller ,如果你有非常大的文件,最好返回FileContentResult甚至FileStreamResult 。 此外,进入yout控制器的模型可以强类型化,MVC ModelBuilder可以轻松地从url字符串中映射它。 所以你的数据对象可以像这样c#类:

 public class CSVData { public string Name { get; set; } public int Count { get; set; } public int SomeId { get; set; } } 

而且您根本不需要在Controller中使用您的数据。 在这里查看更多信息。

 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"); } 

正如你所看到的,在你的情况下你不需要在MVC中使用HttpContext ,你可以做得更干净,更明显。

PS。 如果您的csv对象只是一个byte[]那么您可以像这样写:

  return File(csv, "text/csv", "Custom Report.csv");