Dev_101
Dev_101

Reputation: 53

C# api octet-stream response body to zip file

I have a service which executes a request to a client api that returns a octet-stream response body with the Content-Disposition header in it (This api is meant to return a zip file.). I am using RestSharp and the DownloadData function to get the response as a byte array, but I want to then save the zip file to my local server.

I have tried using DotNetZip and a MemoryStream to create the zip file by using the following example:

using (MemoryStream stream = new MemoryStream(fileBytes))
{
    using (ZipFile zip = new ZipFile())
    {
       zip.AddEntry("test", stream);
       zip.Save(filePath);
    }
}

The code above creates a zip file and an entry called test but I cannot open it. Just to clarify, the zip file I am trying to create contains the following files and folders:

Is there any way to achieve this?

Upvotes: 2

Views: 6173

Answers (3)

Jh2170
Jh2170

Reputation: 166

So i had the same issue Dev_101 had, in which a RestResponse was corrupting the .zip file, however in my case, it was just appending an extra " on the beginning and end, so I just needed to remove the " and Base64Decode it and saved perfectly.

Upvotes: 0

Dev_101
Dev_101

Reputation: 53

For anyone else who encounters this problem, as in saving the byte array to disk and getting a corrupted zip file, I have figured out the answer with the help of Dennis Tretyakov.

Basically, when downloading a octet-stream, the first section of is dedicated to the structure of the zip file. In my case the first section of the zip file was:

--c7c2ad44-881c-47c4-89e5-323f91b75269 Content-Disposition: form-data; name="deb08d79-372d-4de2-a684-1298f25fecd9_20200310142909.zip" Content-Type: application/octet-stream

And thereafter the actual data for the zip file appears after a linebreak.

What I ended up doing was calculating the byte count of the "header" section by converting the byte array to a string:

string stringEncodedBytes = Encoding.ASCII.GetString(response.RawBytes);

Then with knowing the starting point of the zip file data, finding the index of the starting point:

int headerSectionIndex = stringEncodedBytes.IndexOf("PK");

Once I found the index, which in my case always seems to be 178, I simple removed that part of the byte array and then copy the trimmed byte array to a new byte array and write it to disk:

byte[] trimmedFileBytes = new byte[response.RawBytes.Length - headerSectionIndex];
Array.Copy(response.RawBytes, headerSectionIndex, trimmedFileBytes, 0, trimmedFileBytes.Length);

File.WriteAllBytes(filePath, trimmedFileBytes);

I would suggest that anyone struggling with the same issue, open the "corrupted" zip file in notepad++ and take a look at the first section and then determine where the data section of the zip file starts.

The initial zip file data looks like this:

Initial Zip File Data

And the trimmed zip file data looks like this:

Trimmed Zip File Data

Upvotes: 0

Dennis Tretyakov
Dennis Tretyakov

Reputation: 31

As I understood the fileBytes is already a zip file byte stream, what means you don't need to zip it again. Just save as file.

File.WriteAllBytes(filePath, fileBytes);

Upvotes: 1

Related Questions