2016-05-30 7 views
3

でクライアントにzipファイルを返しますコード私は次のエラーを取得する:これが起こるいる理由利用のMemoryStreamとZIPARCHIVE asp.netウェブAPI

$.ajax({ 
    type: "POST", 
    url: url, 
    data: data, 
    dataType: application/x-www-form-urlencoded 
}); 

どれ説明:

ExceptionMessage":"The format of value 'application/zip, application/octet-stream' is invalid."

これは、JSのコードですか?私はあなたの助けを実際にお勧めします

+0

あなたのjavascriptコードを表示してください。代わりにResponseMessage(result)を返そうとしましたか? –

+0

@RicardoPontual更新を参照してください。 ResponseMessage(result)を使用していませんでした。 –

+0

@RicardoPontual result.Content.Headers.ContentTypeの代わりに使用する必要がありますか? –

答えて

4

$.ajaxは、テキスト応答を処理し、しようとしますMediaTypeHeaderValue.TryParseメソッドを使用することができます(UTF-8)は、コンテンツをデコード:zipファイルISN」をtテキスト、あなたは破損したコンテンツを取得します。 jQueryはバイナリコンテンツをサポートしていないので、thisリンクを使用し、jQueryでajaxトランスポートを追加するか、XmlHttpRequestを直接使用する必要があります。 xhrの場合、xhr.responseType = "blob"と設定し、xhr.responseからBLOBを読み取る必要があります。生のXMLHttpRequestと

// with xhr.responseType = "arraybuffer" 
var arraybuffer = xhr.response; 
var blob = new Blob([arraybuffer], {type:"application/zip"}); 
saveAs(blob, "example.zip"); 

// with xhr.responseType = "blob" 
var blob = xhr.response; 
saveAs(blob, "example.zip"); 
Edit: examples: 
jquery.binarytransport.js

(あなたがBLOBまたはArrayBufferをダウンロードしてみましょう任意のライブラリが行います)

$.ajax({ 
    url: url, 
    type: "POST", 
    contentType: "application/json", 
    dataType: "binary", // to use the binary transport 
    // responseType:'blob', this is the default 
    data: data, 
    processData: false, 
    success: function (blob) { 
    // the result is a blob, we can trigger the download directly 
    saveAs(blob, "example.zip"); 
    } 
    // [...] 
}); 

、あなたがthisの質問を参照することができ、あなただけにxhr.responseType = "blob"を追加する必要がありますブロブを取得します。

私個人的には非常に簡単です、jQueryの上のAJAXトランスポートを使用するようにあなたをお勧めします、あなたは、ライブラリをダウンロードし、プロジェクトに含めると記述する必要があります:dataType: "binary".

これはDotNetZipを使用して、APIコードです(Ionic.Zip ):ここでは

[HttpPost] 
    public HttpResponseMessage ZipDocs([FromBody] string[] docs) 
    { 
     using (ZipFile zip = new ZipFile()) 
     { 
      //this code takes an array of documents' paths and Zip them 
      zip.AddFiles(docs, false, ""); 
      return ZipContentResult(zip); 
     } 
    } 

    protected HttpResponseMessage ZipContentResult(ZipFile zipFile) 
    { 
     var pushStreamContent = new PushStreamContent((stream, content, context) => 
     { 
      zipFile.Save(stream); 
      stream.Close(); 
     }, "application/zip"); 

     return new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent }; 
    } 
+0

私は両方を試みたが、私のために働いていない:/私はもうエラーは表示されないが、ファイルはダウンロードされていない ' –

+0

私のバックエンドの部分に何か問題が見えないのですか?http://postimg.org/image/3m861h77f/ –

+0

Consol on the Developersツール(F12)をチェックしましたか?何かエラーがありますか?私は個人的にDotNetZipライブラリを使用し、ZipArchiveを使用しませんでした。 – user3378165

0

MediaTypeHeaderValueのコンストラクタに渡す値のフォーマットは無効です。また、ヘッダー値に複数のコンテンツタイプを追加しようとしています。

コンテンツタイプヘッダは、例えば、セミコロンで区切られたオプションのパラメータが後に続く、;

をシングルタイプ/サブタイプを取ります

Content-Type: text/html; charset=ISO-8859-4 

あなたの結果のためにあなたがしたい1を決定する必要がありつかいます。 application/zipあるいはまた

result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); 

application/octet-streamは、例外を避けるために、あなたは

var contentTypeString = "application/zip"; 
MediaTypeHeaderValue contentType = null; 
if(MediaTypeHeaderValue.TryParse(contentTypeString, out contentType)) { 
    result.Content.Headers.ContentType = contentType; 
} 
+0

暗黙の型変数var contentType = nullにnullを代入することはできません。これは間違っています –

+0

@ Kob_24私はそれを修正しました。 – Nkosi

2

は私のために

のC#側

を働いていた私のソリューションです。今、私はジップに複数のファイルをダウンロードすることができるよ

downloadZip(datas: any) { 
    const headers = new Headers({ 
     'Content-Type': 'application/json', 
     'Accept': 'application/zip' 
    }); 

    const options = new RequestOptions({ headers: headers, withCredentials: true, responseType: ResponseContentType.ArrayBuffer }); 
    const body = JSON.stringify(datas); 
    return this.authHttp.post(`${environment.apiBaseUrl}api/documents/zip`, body, options) 
     .map((response: Response) => { 
      const blob = new Blob([response.blob()], { type: 'application/zip' }); 
      FileSaver.saveAs(blob, 'logs.zip'); 
     }) 
     .catch(this.handleError); 
} 

public IActionResult GetZip([FromBody] List<DocumentAndSourceDto> documents) 
{ 
    List<Document> listOfDocuments = new List<Document>(); 

    foreach (DocumentAndSourceDto doc in documents) 
     listOfDocuments.Add(_documentService.GetDocumentWithServerPath(doc.Id)); 

    using (var ms = new MemoryStream()) 
    { 
     using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
     { 
      foreach (var attachment in listOfDocuments) 
      { 
       var entry = zipArchive.CreateEntry(attachment.FileName); 

       using (var fileStream = new FileStream(attachment.FilePath, FileMode.Open)) 
       using (var entryStream = entry.Open()) 
       { 
        fileStream.CopyTo(entryStream); 
       } 
      } 

     } 
     ms.Position = 0; 
     return File(ms.ToArray(), "application/zip"); 
    } 

    throw new ErrorException("Can't zip files"); 
} 

はここms.Position = 0;

フロント側(角4)をお見逃しなく。

+0

'ms.Position = 0'を呼び出す必要はありません。 [ToArray()](https://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray(v = vs.110).aspx)は、位置に関係なくストリームをバイト配列に書き込みます。 –

+0

@ScottClarkなし期待どおりにコードが動作しない:/ – Fitch

+0

@Fitchダウンロードはすぐに開始されますか?または、すべてのファイルが圧縮されてからダウンロードが開始されるまで待つ必要がありますか? –

関連する問題