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.
我需要将一个大约10-15个短字符串(可能还有一些整数)的集合表示为一个相当紧凑的字母数字字符串 - 我可以在get请求中将其作为参数发送。
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!).
基本上,我认为我的集合将是一个哈希表,我想序列化它,所以它看起来有点像一个viewstate字符串(只希望不那么长!)。
eg. testpage.aspx?code=rO0ABXNyAAlTb21lQ2xhc3PSHbLk6OgfswIAA0kAAWl
and then testpage.aspx can deserialize this back to the original collection.
然后testpage.aspx可以将其反序列化回原始集合。
Is this possible?
这可能吗?
5 个解决方案
#1
One option here is to pick a delimiter, for example ¤; join the strings, encode them (perhaps UTF8), and pack the bytes as base-64...
这里的一个选择是选择一个分隔符,例如¤;加入字符串,对它们进行编码(可能是UTF8),并将字节打包为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).
(您可能需要处理base-64使用的少数非字母数字字符)。
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]);
}
#2
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?
为什么不用protobuf-net序列化数据并将其传递给Session?或者,如果它必须是一个字符串,只需使用XmlSerializer?
Personally, passing serialized data through the URL seems really bad to me!
就个人而言,通过URL传递序列化数据对我来说真的很糟糕!
#3
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.
你可以将你的字典/散列表序列化为JSON,然后将其更改为base64(只是为了让它变得不那么明显并解决URL字符的可能用法等)。或者你可以直接URLEncode它。
#4
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.
您可以使用标准.Net序列化并将对象序列化为MemoryStream。然后,您可以将MemoryStream的内容作为字节数组读出,并使用数组上的Convert.ToBase64String来获取它的字符串表示形式。
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.
如果您担心序列化对象太大,可以将MemoryStream包装在System.IO.Compression.DeflateStream中以压缩它。
#5
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.
我的示例实现了一个DeflateStream,对于我的datasize可能会引入比压缩保存更多的开销。但即使没有压缩,它仍然很大。
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.
我希望实现的是使某些东西稍微更紧凑(对用户进行混淆是一个加分,但并不重要) - 我怀疑使用普通的旧参数化字符串实际上更好。也许JSON可能没关系,但我使用的是ASP.net 2.0,我认为我没有得到一个现成的json序列化器。
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;
}
#1
One option here is to pick a delimiter, for example ¤; join the strings, encode them (perhaps UTF8), and pack the bytes as base-64...
这里的一个选择是选择一个分隔符,例如¤;加入字符串,对它们进行编码(可能是UTF8),并将字节打包为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).
(您可能需要处理base-64使用的少数非字母数字字符)。
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]);
}
#2
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?
为什么不用protobuf-net序列化数据并将其传递给Session?或者,如果它必须是一个字符串,只需使用XmlSerializer?
Personally, passing serialized data through the URL seems really bad to me!
就个人而言,通过URL传递序列化数据对我来说真的很糟糕!
#3
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.
你可以将你的字典/散列表序列化为JSON,然后将其更改为base64(只是为了让它变得不那么明显并解决URL字符的可能用法等)。或者你可以直接URLEncode它。
#4
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.
您可以使用标准.Net序列化并将对象序列化为MemoryStream。然后,您可以将MemoryStream的内容作为字节数组读出,并使用数组上的Convert.ToBase64String来获取它的字符串表示形式。
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.
如果您担心序列化对象太大,可以将MemoryStream包装在System.IO.Compression.DeflateStream中以压缩它。
#5
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.
我的示例实现了一个DeflateStream,对于我的datasize可能会引入比压缩保存更多的开销。但即使没有压缩,它仍然很大。
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.
我希望实现的是使某些东西稍微更紧凑(对用户进行混淆是一个加分,但并不重要) - 我怀疑使用普通的旧参数化字符串实际上更好。也许JSON可能没关系,但我使用的是ASP.net 2.0,我认为我没有得到一个现成的json序列化器。
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;
}