2017-07-18 156 views
1

我有一個Web服務,我可以調用並保存返回的CSV文件。一切似乎都行得通。我現在想做的是返回多個CSV文件供用戶下載。處理這個問題的正確方法是什麼?我猜我需要一種方法來打包它們(zip?也許)?Web服務API服務多個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; 

     } 
     ... 
    } 
+1

是把它們打包成一個zip文件/檔案和下載 – Nkosi

+0

@Nkosi謝謝你,你可以點我,你知道的,我可以引用任何好的資源? –

+1

看看我在這裏給出的答案https://stackoverflow.com/questions/36776704/ziparchive-returning-empty-folder-c-sharp/36777930#36777930你應該能夠修改它以滿足你的需求 – Nkosi

回答

1

使用以下模型

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(); 
      var archive = new ZipArchive(stream: ms, mode: ZipArchiveMode.Create, leaveOpen: false); 
      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(); 
    } 
}