MVC控制器返回CSV,但不使用AJAX下载



在我的控制器中,我使用ServiceStack.Text来序列化List,并希望将其返回到客户端。

我正在传递json,该json被传递并操纵到一个对象列表中,然后我想以csv的形式返回。我可以确认这部分工作正常。客户端报告请求成功,但没有可供下载的文件。如果我console.log响应,它会打印csv字符串。

实际上,我收到了一个json字符串列表,我将其反序列化并附加到一个列表中。我可以再次确认这是按预期进行的。

这是代码:

[ValidateInput(false)]
[HttpPost]
public FileContentResult DownloadCSV(List<string> json, string delimiter, string method)
{
var respCSV ="";
if (method == "combine")
{
List<AgmtToCSV> comb = new List<AgmtToCSV>();
foreach (var i in json)
{
var d = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AgmtToCSV>>(i);
foreach (var u in d)
{
comb.Add(u);
}
}
var csv = CsvSerializer.SerializeToCsv(comb);

respCSV = csv;
}

return File(new System.Text.UTF8Encoding().GetBytes(respCSV), "text/csv", "ExpirationReport.csv");
//return File(respCSV);
}

编辑

以下是响应的样子:

Cache-Control:private
Content-Disposition:attachment; filename=ExpirationReport.csv
Content-Encoding:gzip
Content-Length:3117
Content-Type:text/csv
Date:Thu, 20 Jul 2017 17:42:16 GMT
Server:Microsoft-IIS/8.0
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-AspNetMvc-Version:5.2
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?SDpcZGV2ZWxvcG1lbnRcQWdyZWVtZW50LVZpZXdlclxBViAxLjEuMyBkZXZcQVZcQVZcSG9tZVxEb3dubG9hZENTVg==?=

以下是jquery请求及其如何处理成功响应。。

$.post('@Url.Action("DownloadCSV", "Home")', { "json":dta, "delimiter":del, "method":"combine"}, function (r) {
console.log("Success");
console.log(r);
});

更新-解决方案

能够用公认的答案来实现这一点:成功函数是这里的关键。它创建一个指向下载的链接,然后启动它

$.post('@Url.Action("DownloadCSV", "Home")', { "json":dta, "delimiter":del, "method":"combine"}, function (r) {
console.log("Success");
var link = document.createElement("a");
link.id = "lnkDwnldLnk";
var converted = r;
document.body.appendChild(link);
var csv = converted;
blob = new Blob([csv], { type: 'text/csv' });
window.URL = window.URL || window.webkitURL;
var csvUrl = window.URL.createObjectURL(blob);
var filename = 'ExpirationReport.csv';
$("#lnkDwnldLnk")
.attr({
'download': filename,
'href': csvUrl
});
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv:11./))  // If Internet Explorer, return version number
{
window.navigator.msSaveOrOpenBlob(blob, filename);
}
else {
$('#lnkDwnldLnk')[0].click();
}

document.body.removeChild(link);
}); 

我不确定我的答案是否会完全按照你的意愿,但仍然如此。我使用的这段代码基本上接受了一个JSON对象,将其转换为CSV并下载到浏览器中。

控制器代码,它转到服务以获取对象列表并将其作为JSON返回。

public ActionResult DownLoadExcel(long BatchNumber)
{
Context context = new Context();
IQueryable<string> ICodeList = context.Codes.OrderByDescending(c => c.CreatedDateTime).Where(c => c.BatchNumber == BatchNumber).Select(c => c.Id); ;
var codeList = ICodeList.ToList();

return Json(codeList, JsonRequestBehavior.AllowGet);
}

AJAX调用从控制器获取JSON列表并将其转换为CSV。然后,它创建并伪造一个锚点,并模拟点击它来触发下载

<script type="text/javascript">
function getExcel(batchNumber)
{
$.ajax({
type: 'GET',
url: '@Url.Action("DownloadExcel", "BatchCode")',
data: { BatchNumber: batchNumber },
cache: false,
success: function (result) {
var converted = ConvertToCSV(result);
//this trick will generate a temp "a" tag
var link = document.createElement("a");
link.id = "lnkDwnldLnk";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
var csv = converted;
blob = new Blob([csv], { type: 'text/csv' });
window.URL = window.URL || window.webkitURL;
var csvUrl = window.URL.createObjectURL(blob);
var filename = 'file.csv';
$("#lnkDwnldLnk")
.attr({
'download': filename,
'href': csvUrl
});
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv:11./))  // If Internet Explorer, return version number
{
window.navigator.msSaveOrOpenBlob(blob, filename);
}
else{
$('#lnkDwnldLnk')[0].click();
}

document.body.removeChild(link);
}
});
}

function ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
for (var i = 0; i < array.length; i++) {
var line = array[i];
str += line + 'rn';
}
return str;
}
</script>

最后,您需要并清空HTML 中的

<a hidden="hidden"></a>

最新更新