2017-09-25 98 views
0

我试图从Microsoft Web API 2控制器下载csv文件。这是我到目前为止有: -Angular 2 - 下载csv文件

的Web API: -

[Route("extractContent/{extractId}")] 
    public async Task<IHttpActionResult> GetExtractContent(int extractId) 
    { 
     _logger.Info($"Getting extract file content for extract with id: {extractId}..."); 

     try 
     { 
      IEnumerable<ExtractDto> extracts = await _extractService.GetExtractsAsync(new ExtractSearchRequest { ExtractId = extractId }); 

      ExtractDto extract = extracts?.FirstOrDefault(); 

      if (extract != null) 
      { 
       string path = extract.FilePath; 

       HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 

       var stream = new FileStream(path, FileMode.Open, FileAccess.Read); 

       using (result.Content = new StreamContent(stream)) 
       { 
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
        { 
         FileName = Path.GetFileName(path) 
        }; 
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 

        return Ok(result); 
       } 
      } 
      throw new InvalidOperationException($"Could not find extract with id: {extractId}"); 
     } 
     catch (Exception e) 
     { 
      _logger.ErrorException($"An error occured trying to get extract content for extract with id: {extractId}", e); 

      return InternalServerError(e); 
     } 
    } 

角2下载服务: -

@Injectable() 
export class DownloadService { 
private baseAddress: string; 
private headers: Headers; 
private options: RequestOptions; 

constructor(private http: Http, private config: Config, private errorService: ErrorService) { 
    this.baseAddress = config.cache.get('portfolioUploadApiUrl'); 
    this.headers = new Headers({ 'Content-Type': 'application/json' }); 
    this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType: ResponseContentType.Blob}); 
} 

getExtractContent(extractId: number): Observable<Blob> { 

    return this.http.get(this.baseAddress + 'extractContent/' + extractId, this.options) 
     .map((response: Response) => 
      { 
       return new Blob([response.blob()], {type: 'application/csv'}); 
      } 
     ) 
     .catch(this.errorService.handleError); 
} 

}

角2客户端代码: -

onDownload(): void { 
    if (this.extract && this.extract.FilePath) { 
     this.downloadService.getExtractContent(this.extractId).subscribe(blob => { 
      var date = new Date(); 
      var day = date.getDay(); 
      var month = date.getMonth(); 
      var year = date.getFullYear(); 
      var seconds = date.getSeconds(); 
      var minutes = date.getMinutes(); 
      var hours = date.getHours(); 
      var formattedDate = day + '' + (month + 1) + '' + year + '' + hours + '' + minutes + '' + seconds; 
      var fileName = "Extract" + this.extractId + "-" + formattedDate + ".csv"; 
      FileSaver.saveAs(blob, fileName) 
     }) 
    } 
} 

但是,当我运行do wnload,我得到一个csv文件下载,其中包含以下内容: -

{“Version”:{“_ Major”:1 _Minor:1 _Build:-1 _Revision:-1}内容:{“Headers”: [{“Key”:“Content-Disposition”值:[“attachment; filename = \“RPModel_Portfolio_ISY - 20170925.csv \”“]} {”Key“:”Content-Type“Value:[”application/octet-stream“]}]} StatusCode:200 ReasonPhrase:”OK“Headers:[] RequestMessage:空IsSuccessStatusCode:真正}

谁能帮助

感谢

回答

0

我无法弄清楚如何解决这个问题,所以我只是提供了我的Web API操作中的csv数据的json表示,然后使用Angular2Csv Angular 2库将此json对象转换为CSV文件

由于某种原因,使用ResponseMessage(result)而不是其他Web API包装(如Ok(result))之一意味着CORS被实际请求忽略。 OPTIONS(pre-flight)请求似乎可以工作,但GET在使用ResponseMessage(result)时不会发生,但在使用Ok(result)时会发生,所以我只能假设Ok(result)正在做某些事情来使用Cors功能在网页API 2

0

我有同样的问题从下载的WebAPI一个XML文件

有一个在RequestOptions的差异,有一个二进制的时候。文件(.PDF,.ZIP,...)你可以这样称呼:

this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType: ResponseContentType.Blob}); 

但是,当一个文件是文本文件(.txt,.CSV ......),你必须调用API要求的文本文件,所以:

this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType: ResponseContentType.Text}); 

就我而言,我创建了一个程序从API接收响应并创建通讯文件。

saveFile(data, fileName: string, extentionFile: string) { 
    var mediaType = data.headers.get("Content-Type"); 
    var file; 

    if (extentionFile == "csv") { 
     file = new Blob([data._body], { type: mediaType }) 
    } else { 
     file = new Blob([data.blob()], { type: mediaType }) 
    } 

    FileSaver.saveAs(file, fileName); 
} 

当响应返回一个文本时,您会根据Response的主体创建一个blob。如果返回二进制文件,则可以调用“.blob()”。

我希望它对你有所帮助。

+0

提供我改变了我的代码以匹配你的,但它仍然给我的csv文件 getExtractContent(extractId:数):相同的输出可观测 { 回报this.http.get(这一点。 baseAddress +'extractContent /'+ extractId,this.options) 。map((data:any)=> var mediaType = data.headers.get(“Content-Type”); var body = data._body; return new Blob([body],{type:mediaType} ); } ) .catch(this.errorService.handleError); } – BigBytes

+0

我还将选项更改为: - this.options = new RequestOptions({headers:this.headers,withCredentials:true,responseType:ResponseContentType.Text}); 但这没有什么区别。 我想知道是否因为我在WebAPI行动中这样做: - 好的(结果) – BigBytes

+0

所以我改变了我的web api action来返回一个ResponseMessage(result),但现在我得到了一个500内部服务器错误,GET请求的资源上出现“No-Access-Control-Allow-Origin'标头,原因'http:// localhost:4200'因此不被允许访问。可怕的CORS错误。 OPTIONS飞行前请求以200响应,但GET响应500以及上述错误消息。有任何想法吗? – BigBytes