我有一个可以调用的Web服务并保存返回的csv文件。一切似乎都运转正常。我现在感兴趣的是返回多个CSV文件供用户下载。处理这个问题的正确方法是什么?我猜我需要一种方法来打包它们(拉链?也许)?
[HttpPost]
[Route("OutputTemplate")]
public HttpResponseMessage OutputTemplate()
{
HttpResponseMessage msg = new HttpResponseMessage();
string body = this.Request.Content.ReadAsStringAsync().Result;
try
{
string contents = DoStuff(body) // get contents based on body
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(contents);
writer.Flush();
stream.Position = 0;
msg.StatusCode = HttpStatusCode.OK;
msg.Content = new StreamContent(stream);
msg.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
msg.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "fileexport"
};
return msg;
}
...
}
答案 0 :(得分:3)
使用以下模型抽象文件名和内容
public class FileModel {
public string FileName { get; set; }
public byte[] FileContent { get; set; }
}
导出以下扩展名以压缩文件内容
public static class ZipArchiveExtensions {
public static Stream Compress(this IEnumerable<FileModel> files) {
if (files.Any()) {
var ms = new MemoryStream();
using(var archive = new ZipArchive(
stream: ms,
mode: ZipArchiveMode.Create,
leaveOpen: true
)){
foreach (var file in files) {
var entry = archive.add(file);
}
}
ms.Position = 0;
return ms;
}
return null;
}
private static ZipArchiveEntry add(this ZipArchive archive, FileModel file) {
var entry = archive.CreateEntry(file.FileName, CompressionLevel.Fastest);
using (var stream = entry.Open()) {
stream.Write(file.FileContent, 0, file.FileContent.Length);
}
return entry;
}
}
有了这个,示例API控制器操作可能看起来像这样。
public class ExampleApiController : ApiController {
public async Task<IHttpActionResult> OutputTemplate() {
IHttpActionResult result = BadRequest();
var body = await Request.Content.ReadAsStreamAsync();
List<FileModel> files = DoSomething(body);
if (files.Count > 1) {
//compress the files.
var archiveStream = files.Compress();
var content = new StreamContent(archiveStream);
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
response.Content = content;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
FileName = "fileexport.zip"
};
result = ResponseMessage(response);
} else if (files.Count == 1) {
//return the single file
var fileName = files[0].FileName; //"fileexport.csv"
var content = new ByteArrayContent(files[0].FileContent);
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
response.Content = content;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
FileName = fileName
};
result = ResponseMessage(response);
}
return result;
}
private List<FileModel> DoSomething(System.IO.Stream body) {
//...TODO: implement file models
throw new NotImplementedException();
}
}