简体   繁体   中英

How to serialize a collection as an alphanumeric string?

I need to express a collection of about 10-15 short strings (and maybe some ints) as a fairly compact alphanumeric string - one which I can send as a parameter in a get request.

Basically, I'm thinking that my collection will be a hashtable, and I'd like to serialize it so it looks sort of like a viewstate string (only hopefully not so long!).

eg. testpage.aspx?code=rO0ABXNyAAlTb21lQ2xhc3PSHbLk6OgfswIAA0kAAWl

and then testpage.aspx can deserialize this back to the original collection.

Is this possible?

One option here is to pick a delimiter, for example ¤; join the strings, encode them (perhaps UTF8), and pack the bytes as base-64...

    string[] data = {"abc","123", "def"};
    string s = string.Join("¤", data);
    byte[] raw = Encoding.UTF8.GetBytes(s);
    string alphaNumeric = Convert.ToBase64String(raw); // send this

(you may need to handle the few non-alphanumeric characters that base-64 uses).

And to reverse it:

    raw = Convert.FromBase64String(alphaNumeric);
    s = Encoding.UTF8.GetString(raw);
    data = s.Split('¤');

If you want to send key/value pairs... well, the obvious choice would be query-string parameters themselves, since they are designed for this. But if you need it as a byte-stream:

    var data = new DbConnectionStringBuilder();
    data["foo"] = "abc";
    data["bar"] = "123 + ;la";
    string s = data.ConnectionString;

    byte[] raw = Encoding.UTF8.GetBytes(s);
    string alphaNumeric = Convert.ToBase64String(raw); // send this

    raw = Convert.FromBase64String(alphaNumeric);
    s = Encoding.UTF8.GetString(raw);
    data.ConnectionString = s;
    foreach (string key in data.Keys)
    {
        Console.WriteLine(key + "=" + data[key]);
    }

Why don't you just serialize the data using protobuf-net and pass it through the Session? Or, if it has to be a string, just use XmlSerializer?

Personally, passing serialized data through the URL seems really bad to me!

you can serialize your dictionary/hashtable to JSON, and then change it to base64 (just to make it a tad less visible and resolve possible usage of URL characters etc). or you can just URLEncode it.

You can use standard .Net serialization and serialize your object to a MemoryStream. You can then read out the contents of the MemoryStream as a byte array and use Convert.ToBase64String on the array to get a string representation of it.

To deserialize it you can do the opposite.

If you are worried that the serialized object is too large, you can wrap the MemoryStream in a System.IO.Compression.DeflateStream to compress it.

Thank you all, putting it together I wrote a test console app. I was a bit disappointed that the resulting string was so long.

My example implements a DeflateStream, which for my datasize probably introduces more overhead than it saves with compression. But even without the compression it was still pretty big.

What I was hoping to achieve was to make something slightly more compact (obfuscation for the user was a plus, but not critical) - I suspect that it'd actually be better for me to use a plain old parameterized string. Maybe JSON might be ok, but I'm using ASP.net 2.0, and I don't think that I get a readybaked json serializer there.

Nonetheless, I learnt something new and interesting, so thanks for that!

    static void Main(string[] args)
    {
        Hashtable ht1 = new Hashtable(1);
        ht1.Add("name", "bob");
        Console.WriteLine(ToCompactString(ht1));

        Console.WriteLine();

        string str = "name:bob";
        Console.WriteLine(ToCompactString(str));
        Console.ReadLine();
    }

    private static string ToCompactString(object obj)
    {
        var ms = new MemoryStream();
        var ds = new DeflateStream(ms, CompressionMode.Compress);
        var bf = new BinaryFormatter();

        bf.Serialize(ds, obj);
        byte[] bytes = ms.ToArray();
        ds.Close();
        ms.Close();
        string result = Convert.ToBase64String(bytes);
        return result;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM