Resolved Zip File Download Corrupts Only AFter Deployed to Server

Madaxe

Member
Joined
Aug 15, 2020
Messages
13
Programming Experience
5-10
Morning,

I have a very interesting situation, when i run my code locally with the IIS express it works great the zip file is downloaded fine. After publishing to AWS Lambda the zip file downloads but is corrupt. I'm trying to understand if its the way in which the controller returns the memory stream or if its an AWS issue. I have submitted a ticket to AWS, can anybody see an issue with my controller that would cause this issue.

Things I've tried

  1. result .Seek(0, SeekOrigin.Begin);
  2. result .Position = 0;
  3. "application/zip"
  4. byte[] test = result.ToArray(); and returning the array

p.s i know I'm going to get crap for my coding style........lol....


C#:
        [HttpPost("v1/GetReaJetXMLZips")]
        public IActionResult GetReaJetXMLZips([FromBody] IEnumerable<JsonRequestModel> JsonRequestModels)
        {
            try
            {
                string FileName = string.Concat("ReaJet_", DateTime.Now.ToString("yyyyMMddhhmmss"), ".zip");
                MemoryStream result = this._IReaJetPOCImpl.GetReaJetXMLZips(JsonRequestModels);
                return File(result, "application/octet-stream", FileName);
            }
            catch(Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }
 

Attachments

  • ReaJet_20200817091447_GOOD.zip
    13.9 KB · Views: 31
  • ReaJet_20200817071410_BAD.zip
    18.7 KB · Views: 31
Last edited:
The bad one is a base64 encoded string, if you convert it and save the bytes it is a valid zip file. (Convert.FromBase64String)
I'm not sure exactly, but perhaps try MIME type "application/zip" ? MimeMapping.GetMimeMapping actually returns "application/x-zip-compressed" for zip extensions, so maybe that is better.
 
The bad one is a base64 encoded string, if you convert it and save the bytes it is a valid zip file. (Convert.FromBase64String)
I'm not sure exactly, but perhaps try MIME type "application/zip" ? MimeMapping.GetMimeMapping actually returns "application/x-zip-compressed" for zip extensions, so maybe that is better.

Might need a little help... i tried this but the server throws a 500


C#:
        [HttpPost("v1/GetReaJetXMLZips")]
        public IActionResult GetReaJetXMLZips([FromBody] IEnumerable<JsonRequestModel> JsonRequestModels)
        {
            try
            {
                string FileName = string.Concat("ReaJet_", DateTime.Now.ToString("yyyyMMddhhmmss"), ".zip");
                MemoryStream result = this._IReaJetPOCImpl.GetReaJetXMLZips(JsonRequestModels);
                byte[] filebytes = new byte[result.Length];
                result.Read(filebytes, 0, Convert.ToInt32(result.Length));
                string test= Convert.ToBase64String(filebytes);

                return File(test, "application/zip", FileName);
            }
            catch(Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }
 
So by playing around i was able to replicate on my local machine a 64bit encode zip which looked like the bad zipfile same size and same issue when trying to open. I have made several attempts to convert to a 32bit encoded zip but im really stuck any help would be great here is my latest attempt same bad result

or just maybe i plainly don't understand


C#:
        [HttpPost("v1/GetReaJetXMLZips")]
        public IActionResult GetReaJetXMLZips([FromBody] IEnumerable<JsonRequestModel> JsonRequestModels)
        {
            try
            {
                string FileName = string.Concat("ReaJet_", DateTime.Now.ToString("yyyyMMddhhmmss"), ".zip");
                MemoryStream result = this._IReaJetPOCImpl.GetReaJetXMLZips(JsonRequestModels);

                byte[] byteArray = result.ToArray();
                string encodedText = Convert.ToBase64String(byteArray);
                byte[] bytes = Convert.FromBase64String(encodedText);

                MemoryStream result2 = new MemoryStream();
                result2.Write(bytes, 0, bytes.Length);
                result2.Seek(0, SeekOrigin.Begin);

                return File(result2, "application/octet-stream", FileName);
            }
            catch(Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }
 
I understand the method you had in post 1 returned correct bytes, but the caller received that as base64 encoded string. I'm not familiar with the codes have posted and can't help with that, I just knew what the attachments you posted were. Base64 is common in web environment for transport of byte content, but how and in which environment you are using your codes I have no idea.
 
we just found out that the APIGateway on Amazon''s end is automatically encoding to base64, so it doesn't matter what you do on the Lambda side you have to receive the stream on a client side app and decode, we just proved this out by creating a small application. I'm logging a ticket with amazon to see if there is a workaround.
 
My reading of this is that not only do you have to tell the AWS API Gateway that you are returning binary data, but the requestor for the data also needs to indicate that it can accept binary data:


So this is already starting away from C#, but what does the HTTP request look like? Is it an AJAX call? What headers are passed in that AJAX call?
 
Back
Top Bottom