0

I'm working in a solution with SOA architect, and I have got an issue converting a .zip file in a byte array on WS Layer and download by a web API from the presentation layer.

The zip file download is successful, but it's not possible to unzip the file. Let me explain with code:

Business Layer

On business layer we've defined a method that converts a file zip on a byte array

//This method is defined on business layer and exposed on WS in WCF Layer
//Class: BusinessLayer
public byte[] convertingZip(){
    try{
        pathFile = "directoryOnServer/myZipFile.zip"
        byte[] arr = File.ReadAllBytes(pathFile);
        return arr; 

    }catch(Exception ex){ /*Do something*/ }

}

WCF Services Layer

On WCF services layer, we code a method that returns the array bytes and exposed it

//Class: ServiceLayer
public  byte[] getByteArray(){
    try{
        BusinessLayer blObject = new BusinessLayer();
        return blObject.convertingZip();    
    }catch(Exception ex){ /*Do something*/ }
}

Web API

On Web API project, we code a method that consumes the WCF service layer and return byte array into content

//This controller must be return the zip file
[HttpGet]
[AuthorizeWebApi]
[Route("downloadZip")]
public async Task<IHttpActionResult> downloadZipFile(){
    try{
        using(ServiceLayer services = new ServiceLayer()){
            arr = services.getByteArray();

            var result = new HttpResponseMensage(HttpStatusCode.OK){
                Content = new ByteArrayContent(arr); }

            result.Content.Headers.ContentDisposition 
               = new ContentDispostionHeaderValue("attachment"){
                FileName = "zip-dowload.zip" };

            result.Content.Headers.ContentType 
               = new MediaTypeHeaderValue("application/octec-stream");

            var response = ResponseMessage(result);
            return result;
        }
    }cacth(Exception ex){ /*Do something*/ }
}

Presentation Layer

On presentation layer I download the file with angular JS 1.6.5

//On Web App project  consume the WebApi with Angular
//MyController.js

$scope.DonwloadZip = function(){
$http.get('api/myControllerUrlBase/downloadZip')
    .success(function(data, status, headers, config){
            if(status === true && data != null){
                var file = new Blob([data], {type: "application/zip"});
                var fileURL = URL.createObjectUrl(file);
                var a = document.createElement(a);
                a.href = fileURL;
                a.target = "_blank";
                a.download = "MyZipFileName.zip";
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            }else { /*Do something */}
    })
    .error(function(data, status, headers, config) {
            //show error message
    });
}

I'm not sure that doing right. I test some similar with .xml, .txt. and .csv files and works. But don't work with zip files.

Then, What is the correct way to convert a zip file in a byte array and getting my web API from web app project?

I'll very grateful for help.

2 Answers 2

1

Well, I've resolve the issue and I would like share the solution.

The central problem it's on web-api and presentation layer, then we need modify the code here:

On Api Controller, convert the byte array into a string on base64 and send on http response content

[HttpGet]
[AuthorizeWebApi]
[Route("downloadZip")]
public async Task<IHttpActionResult> downloadZipFile(){
    try{
    //Using WS reference
        using(ServiceLayer services = new ServiceLayer()){

        //Catch the byte array
        arr = services.getByteArray();

        //Encode in base64 string
        string base64String = System.Convert.ToBase64String(arr, 0, arr.length);    

        //Build the http response       
            var result = new HttpResponseMensage(HttpStatusCode.OK){
                Content = new StringContent(base64String); }

            result.Content.Headers.ContentDisposition 
               = new ContentDispostionHeaderValue("attachment"){
                FileName = "zip-dowload.zip" };

            result.Content.Headers.ContentType 
               = new MediaTypeHeaderValue("application/octec-stream");

            var response = ResponseMessage(result);
            return result;
        }
    }cacth(Exception ex){ /*Do something*/ }
}

On Angular Controller, no convert data response on Blob, define metadata about data response and download:

$scope.DonwloadZip = function(){
$http.get('api/myControllerUrlBase/downloadZip')
    .success(function(data, status, headers, config){
            if(status === true && data != null){

                //No convert data on Blob
                var fileURL = 'data:application/octec-stream;charset=utf-8;base64,'+ data;
                var a = document.createElement(a);
                a.href = fileURL;
                a.target = "_blank";
                a.download = "MyZipFileName.zip";
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            }else { /*Do something */}
    })
    .error(function(data, status, headers, config) {
            //show error message
    });
}

Remember that if you're using a Angular 1.6.5 or up version, http request must be something like:

   $http({
      method: 'GET',
      url: 'api/myControllerUrlBase/downloadZip'
   }).then(function (response){
       //Success
   },function (error){
       //Error
   });

I hope that be useful for somebody, thanks for try help!

Sign up to request clarification or add additional context in comments.

Comments

0

I can achieved this from below method

downloadFile(base64: string,filename: string, mimetype: string) {
var fileURL = 'data:application/octec-stream;charset=utf-8;base64,' + base64;
var a = document.createElement('a');
a.href = fileURL;
a.target = "_blank";
a.download = filename + ".pdf";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);

}

<a [href]="fileUrl" (click)="downloadFile(type.base64String,type.name,type.extension)"> {{type.name}}

1 Comment

As it stands, your answer is unclear and could use some explanation and reformatting. Please refer to stackoverflow.com/help/how-to-answer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.