从MVC的Web API HTT presponse生成CSV和angularjs下载收到 [英] generate csv from mvc web api httpresponse and receive it by angularjs for download
问题描述
我想生成从我的网页API一个CSV文件,并通过angularjs收到该文件。我有一个API控制器象下面这样:
[HttpPost]
公众的Htt presponseMessage GenerateCSV(FieldParameters fieldParams)
{
无功输出=新的字节[] {};
如果(fieldParams!= NULL)
{
使用(VAR流=新的MemoryStream())
{
this.Serialize(fieldParams,流);
stream.Flush();
输出= stream.ToArray();
}
}
VAR的结果=新的Htt presponseMessage(的HTTPStatus code.OK){内容=新ByteArrayContent(输出)};
result.Content.Headers.ContentType =新MediaTypeHeaderValue(应用程序/八位字节流);
result.Content.Headers.ContentDisposition =新ContentDispositionHeaderValue(附件)
{
文件名=Fields.csv
};
返回结果;
}
在我angularjs,我有这样的:
$ scope.save =功能(){
变种csvInput = extractDetails(); //文件是一个棱角分明的资源。我们把它保存方法在这里它
//访问高于它应该会返回CSV内容的API
File.save(csvInput,功能(内容){
的console.log(内容); //只创建了一个CSV文件的翻译:写在上面
VAR hiddenElement =使用document.createElement('A');
hiddenElement.href ='数据:文本/ CSV;字符集= UTF-8,\\ uFEFF'+ EN codeURI(content.Parameters);
hiddenElement.target =_blank;
hiddenElement.download ='myFile.csv';
hiddenElement.click();
});
};
让我们说,例如,在我的API控制器,响应的内容是
输出
{字节[152]}
[0]:83
[1]:101
[2]:44
[3]:67
[4]:10
块引用>当我收到这在 angularjs 并我把
在控制台日志(铬)含量
的价值,这是我得到:
{参数:Array [1],$承诺:对象,$解决:真实,$得到:函数,$保存:函数...}
0:S
1:E
2:,
3:C
4:↵
$承诺:对象
$解决:TRUE`
块引用>
为什么
内容
在angularjs收到包含的字符
已经代替阵列的一个字节?我如何控制
内容
以这样的方式,我将只使用
该CSV相关的数据,并删除$承诺
和$解决
?为什么他们列入摆在首位?如何删除他们?什么是,如果我做的是产生一个CSV文件的正确方法
错误? :|解决方案忘了更新,但我现在发现一个方法来解决这个问题:
有将两个API的,一个(POST)会记得在加工中使用的数据和另一个(GET),这将分配所述文件
POST:
[HttpPost]
公共异步任务< Htt的presponseMessage>构建文件(FileParameters fileParams)
{
VAR GUID = Guid.NewGuid()的ToString()。
如果(fileParams!= NULL)
{
等待Task.Run(()=> FileContents.Add(GUID,fileParams));
返回this.Request.CreateResponse(的HTTPStatus code.OK,新的{值= GUID});
}
返回this.Request.CreateErrorResponse(的HTTPStatus code.BadRequest,无效数据);
}在AngularJs,记住返回的GUID和它传递给另一个API:
location.href ='/ API /文件/ generatefile'+ + + generatedGuidFromAPIGUID =?''和,所以reportName ='+ $ scope.reportName;
这是MVC中的
generatefile
API控制器:GET:
[HTTPGET]
公共异步任务< Htt的presponseMessage> GenerateFile(GUID字符串,字符串所以reportName)
{
字节[]输出= NULL;
如果(FileContents.ContainsKey(GUID))
{
等待Task.Run(()=>
{
使用(VAR流=新的MemoryStream())
{
this.CreateFile(FileContents [GUID],流);
stream.Flush();
输出= stream.ToArray();
}
});
} FileContents.Remove(GUID);
如果(输出!= NULL)
{
VAR的结果=新的Htt presponseMessage(的HTTPStatus code.OK){内容=新ByteArrayContent(输出)};
result.Content.Headers.ContentType =新MediaTypeHeaderValue(应用程序/八位字节流);
result.Content.Headers.ContentDisposition =新ContentDispositionHeaderValue(附件)
{
文件名= +所以reportName的.csv
};
返回结果;
} 返回this.Request.CreateErrorResponse(的HTTPStatus code.NoContent,没有找到记录);
}使用
location.href
将导致浏览器自动下载文件,询问是否保存与否。I am trying to generate a CSV file from my web api and receive that file through angularjs. I have an API controller like below:
[HttpPost] public HttpResponseMessage GenerateCSV(FieldParameters fieldParams) { var output = new byte[] { }; if (fieldParams!= null) { using (var stream = new MemoryStream()) { this.Serialize(fieldParams, stream); stream.Flush(); output = stream.ToArray(); } } var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(output) }; result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "Fields.csv" }; return result; }
In my angularjs, i have this:
$scope.save = function () { var csvInput= extractDetails(); // File is an angular resource. We call its save method here which // accesses the api above which should return the content of csv File.save(csvInput, function (content) { console.log(content); // only creates a csv file with "[object Object]" written in it var hiddenElement = document.createElement('a'); hiddenElement.href = 'data:text/csv;charset=utf-8,\uFEFF' + encodeURI(content.Parameters); hiddenElement.target = '_blank'; hiddenElement.download = 'myFile.csv'; hiddenElement.click(); }); };
Lets say for example, in my API controller, the content of response is
output
{byte[152]}
[0]: 83
[1]: 101
[2]: 44
[3]: 67
[4]: 10
When I receive this in angularjs and I put the value of
content
in the console log (chrome), this is what I get:{Parameters: Array[1], $promise: Object, $resolved: true, $get: function, $save: function…}
0:"S"
1: "e"
2: ","
3: "C"
4: "↵"
$promise: object
$resolved: true`
Why did the
content
received in the angularjs contain characters already instead of a byte of array?How can I control the
content
in such a way that I will only use the csv related data and remove$promise
and$resolved
? Why are they included in the first place? How to remove them?What is the proper way of generating a csv if what I am doing is wrong? :|
解决方案Forgot to update this, but i now found a way to solve this:
There will be two API's, one (POST) will remember the data to be used in the processing and another one (GET) which will dispense the file.
POST:
[HttpPost] public async Task<HttpResponseMessage> BuildFile(FileParameters fileParams) { var guid = Guid.NewGuid().ToString(); if (fileParams!= null) { await Task.Run(() => FileContents.Add(guid, fileParams)); return this.Request.CreateResponse(HttpStatusCode.OK, new { Value = guid }); } return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid data"); }
In AngularJs, remember the guid returned and pass this to another api:
location.href = '/api/file/generatefile' + '?guid=' + generatedGuidFromAPI + '&reportName=' + $scope.reportName;
And here is the
generatefile
API controller in MVC:GET:
[HttpGet] public async Task<HttpResponseMessage> GenerateFile(string guid, string reportName) { byte[] output = null; if (FileContents.ContainsKey(guid)) { await Task.Run(() => { using (var stream = new MemoryStream()) { this.CreateFile(FileContents[guid], stream); stream.Flush(); output = stream.ToArray(); } }); } FileContents.Remove(guid); if (output != null) { var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(output) }; result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = reportName + ".csv" }; return result; } return this.Request.CreateErrorResponse(HttpStatusCode.NoContent, "No record found"); }
using
location.href
will cause the browser to automatically download the file, asking you whether to save it or not.这篇关于从MVC的Web API HTT presponse生成CSV和angularjs下载收到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!