Javascript GZIP和btoa,并使用C#

时间:2019-04-14 21:47:46

标签: base64 compression gzip

我正在开发一个应用程序,其中我使用pako.gzip压缩大型JSON数据,然后使用btoa函数将其设置为base64string以便将数据发布到服务器。在我写的JavaScript中:

    var data = JSON.stringify(JSONData);
    var ZippedData = pako.gzip(data, { to: 'string' });
    var base64String = btoa(ZippedData);
    /* post to server*/
    $http.post("URL?base64StringParam=" + base64String").then(function (response) {
        //do stuff
    });

问题是我需要在发布后再次用C#代码解压缩数据以便对其进行其他工作。在C#代码中,我写道:

    byte[] data = Convert.FromBase64String(base64StringParam);
            string decodedString = System.Text.ASCIIEncoding.ASCII.GetString(data);
            Encoding enc = Encoding.Unicode;
            MemoryStream stream = new MemoryStream(enc.GetBytes(decodedString));
            GZipStream decompress = new GZipStream(stream, CompressionMode.Decompress);
            string plainDef = "";

我在这里得到错误

    using (var sr = new StreamReader(decompress))
            {
                plainDef = sr.ReadToEnd();
            }

解码时发现无效数据。

任何帮助将数据解压缩回C#的方式将受到赞赏

编辑:总结需要做的事情 javascript执行以下操作:

纯文本>>到>> gzip字节>>到>> base64字符串

我需要C#来做相反的事情:

Base64 >>到>>解压缩字节>>到>>纯文本

2 个答案:

答案 0 :(得分:0)

假设以下js:

dataToCommitString = btoa(pako.gzip(dataToCommitString, { to: "string" }));

这是使用GZip压缩/解压缩的正确c#代码:取自https://stackoverflow.com/a/7343623/679334

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YourNamespace
{

    public class GZipCompressor : ICompressor
    {
        private static void CopyTo(Stream src, Stream dest)
        {
            byte[] bytes = new byte[4096];

            int cnt;

            while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
            {
                dest.Write(bytes, 0, cnt);
            }
        }

        public byte[] Zip(string str)
        {
            var bytes = Encoding.UTF8.GetBytes(str);

            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(mso, CompressionMode.Compress))
                {
                    //msi.CopyTo(gs);
                    CopyTo(msi, gs);
                }

                return mso.ToArray();
            }
        }

        public string Unzip(byte[] bytes)
        {
            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(msi, CompressionMode.Decompress))
                {
                    //gs.CopyTo(mso);
                    CopyTo(gs, mso);
                }

                return Encoding.UTF8.GetString(mso.ToArray());
            }
        }
    }
}

调用如下:

value = _compressor.Unzip(Convert.FromBase64CharArray(value.ToCharArray(), 0, value.Length));

答案 1 :(得分:0)

在客户端使用:

let output = pako.gzip(JSON.stringify(obj));

发送为:'Content-Type':'application/octet-stream'

======================

然后在 C# 中:

[HttpPost]
[Route("ReceiveCtImage")]
public int ReceiveCtImage([FromBody] byte[] data)
{
    var json = Decompress(data);
    return 1;     
}

public static string Decompress(byte[] data)
{
    // Read the last 4 bytes to get the length
    byte[] lengthBuffer = new byte[4];
    Array.Copy(data, data.Length - 4, lengthBuffer, 0, 4);
    int uncompressedSize = BitConverter.ToInt32(lengthBuffer, 0);

    var buffer = new byte[uncompressedSize];
    using (var ms = new MemoryStream(data))
    {
        using (var gzip = new GZipStream(ms, CompressionMode.Decompress))
        {
            gzip.Read(buffer, 0, uncompressedSize);
        }
    }
    string json = Encoding.UTF8.GetString(buffer); 
    return json;
}