如何使用jQuery Ajax调用从ASP.NET Web Api下载CSV文件

我正在研究如何从jQuery ajax调用从ASP.NET Web Api下载CSV文件。 CSV文件是基于自定义CsvFormatter从Web API服务器动态生成的。

来自jQuery的Ajax:

$.ajax({ type: "GET", headers: { Accept: "text/csv; charset=utf-8", }, url: "/api/employees", success: function (data) { } }); 

在服务器上, EmployeeCsvFormatter的实现类似于以下文章,派生自BufferedMediaTypeFormatter

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

 public class EmployeeCsvFormatter : BufferedMediaTypeFormatter { public EmployeeCsvFormatter() { SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv")); } ... } 

我还添加了覆盖方法来表示我想像下载文件一样下载文件(可以在下载选项卡中看到下载文件):

  public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { base.SetDefaultContentHeaders(type, headers, mediaType); headers.Add("Content-Disposition", "attachment; filename=yourname.csv"); headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); } 

但它不起作用,下载文件没有显示在状态栏或Chrome上的下载选项卡中,即使来自Fiddler,我看到它的响应似乎是正确的:

 HTTP/1.1 200 OK Server: ASP.NET Development Server/11.0.0.0 Date: Mon, 11 Mar 2013 08:19:35 GMT X-AspNet-Version: 4.0.30319 Content-Disposition: attachment; filename=yourname.csv Cache-Control: no-cache Pragma: no-cache Expires: -1 Content-Type: application/octet-stream Content-Length: 26 Connection: Close 1,Cuong,123 1,Trung,123 

我从ApiController的方法:

 public EmployeeDto[] Get() { var result = new[] { new EmployeeDto() {Id = 1, Name = "Cuong", Address = "123"}, new EmployeeDto() {Id = 1, Name = "Trung", Address = "123"}, }; return result; } 

在某些我没想到的地方一定是错的。 如何通过正常方式下载CSV文件来使其工作?

请求Ajax类文件下载的jQuery插件 使用简单的表单提交没有Ajax。

内部:

 jQuery('
'+inputs+'
') .appendTo('body').submit().remove()

它有一个ajax风格的界面,所以从外面你可以像这样调用它

 $.download('/api/employees','format=csv'); 

另一种简单的方法:

 $('#btnDownload').click(function (e) { e.preventDefault(); window.location = "/api/employees?format=csv"; }); 

在服务器上,必须通过添加一个构造函数来使用MediaTypeMappings

  public EmployeeCsvFormatter(MediaTypeMapping mediaTypeMapping) : this() { MediaTypeMappings.Add(mediaTypeMapping); } 

然后,将此格式化程序添加到Web Api配置中:

  configuration.Formatters.Add(new EmployeeCsvFormatter (new QueryStringMapping("format", "csv", "text/csv"))); 

作为替代方法,可以通过单击锚点()或按钮提供下载,其中请求的URL设置为响应附件的API方法。

CsvMediaTypeFormatter (派生自System.Net.Http.Formatting.MediaTypeFormatter)中,除了映射text / csv MIME类型(如上面的答案所示)之外,我还发现需要完成以下工作:

 public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { base.SetDefaultContentHeaders(type, headers, mediaType); headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = string.Concat("data", DateTime.UtcNow.ToString("yyyyMMddhhmmss"), ".csv") }; headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); } 

注意:编写流时,请设置Content-Length标头并记住刷新流。 我发现没有调用Flush() ,即使设置了正确的内容长度,返回的响应也不会成功返回到客户端。

您还可以通过修改xhr在beforeSend中设置请求标头。

  $.ajax({ url: "/api/employees", type: "GET", beforeSend: function (xhr) { xhr.setRequestHeader("Accept", "text/csv"); }, success: function (data) { } });