Serialization in .NET 2.0
-
Is there a built-in way to serialize and deserialize an IDictionary<string, string> to XML or JSON in .NET 2.0?
I'm restricted to .NET 2.0 because the Launchy# library doesn't seem to support anything newer. I can use an external library, but I'd prefer not to have a bunch of additional files alongside my DLL that actually does the needful.
-
@hungrier said in Serialization in .NET 2.0:
I can use an external library, but I'd prefer not to have a bunch of additional files alongside my DLL that actually does the needful.
You can bundle dependencies as embedded resources in your assembly, and load them dynamically at runtime.
-
@error Sounds horrible, but that could be a way to do it.
-
@hungrier said in Serialization in .NET 2.0:
I'm restricted to .NET 2.0 because the Launchy# library doesn't seem to support anything newer.
Shouldn't that actually restrict you to .NET 3.5, since it's all the same runtime?
Is there a built-in way to serialize and deserialize an IDictionary<string, string> to XML or JSON in .NET 2.0?
If .NET 3.5 truly is available, you have
DataContractJsonSerializer
for JSON.For XML, I think you'd need to subclass
Dictionary<string, string>
and implement theIXmlSerializable
interface.
-
@Unperverted-Vixen I didn't know that about 3.5. I'll have to try it. When I started working on the project I tried 4.5 and it didn't go at all, and since the sample that came with the library was 2.0 I figured that would be all I could do.
I'm actually leaning more toward XML since it would make it slightly more human-friendly with regard to not having to escape stuff, if someone theoretically wanted to manually edit the file (and, even more theoretically, if I wasn't the only user)
-
@hungrier said in Serialization in .NET 2.0:
I'm actually leaning more toward XML since it would make it slightly more human-friendly with regard to not having to escape stuff, if someone theoretically wanted to manually edit the file (and, even more theoretically, if I wasn't the only user)
Both XML and JSON are really not very readable, not when machine generated. There are tools that can help… a bit… with reading, but even so.
-
@dkf I think it's readable enough for someone who can install a Launchy plugin, or even uses Launchy (so just me)
-
@hungrier If it's just the external library that's a problem, couldn't you use ILMerge?
-
@Zenith said in Serialization in .NET 2.0:
@hungrier If it's just the external library that's a problem, couldn't you use ILMerge?
TILMerge
-
@error said in Serialization in .NET 2.0:
TIL(Merge)
I just learned about it the other day. Nice tool. Merged eight or so DLLs into an executable so I could just deliver it as one file.
One bug I ran into though: If I didn't specify /targetplatform:v4, ILMerge just hung forever. Not sure if that was specific to my assemblies and their targeted platform, though I know I'm not the only one since I found that answer on SO.
-
I ended up making my own crappy version, but at least with an interface so I can later replace it with something better if I ever want to.
e: my own crappy plaintext serialization, not XML or anything.
-
@hungrier said in Serialization in .NET 2.0:
my own crappy plaintext serialization, not XML or anything
The hardest part of writing a serialization format (or its implementation) is remembering to cover all the tricky edge cases.
-
@dkf That's true, and my current implementation basically just relies on not having any key/value boundaries appear in the text with no guarantee of what happens if they get in there.
-
@hungrier said in Serialization in .NET 2.0:
I ended up making my own crappy version
You're not using enough
violenceXML. Are you even a real modern programmer?public static void Serialize<K, V>(this IDictionary<K, V> dict, Stream o) { var doc = new XmlDocument(); doc.AppendChild(doc.CreateXmlDeclaration("1.0", "UTF-16", null)); var items = doc.CreateElement("items"); doc.AppendChild(items); foreach (var entry in dict) { var item = doc.CreateElement("item"); items.AppendChild(item); var key = doc.CreateElement("key"); key.InnerText = entry.Key.ToString(); item.AppendChild(key); var val = doc.CreateElement("value"); val.InnerText = entry.Value?.ToString(); item.AppendChild(val); } doc.Save(o); o.Flush(); } public delegate bool TryParse<T>(string k, out T value); public static void Unserialize<K, V>(this IDictionary<K, V> dict, TryParse<K> keyparse, TryParse<V> valparse, Stream i) { var doc = new XmlDocument(); doc.Load(i); var items = doc.SelectSingleNode("items"); var itemlist = items.SelectNodes("item"); foreach (XmlNode item in items) { var keynode = item.SelectSingleNode("key"); var valnode = item.SelectSingleNode("value"); if (keyparse.Invoke(keynode.InnerText, out K key) && valparse.Invoke(valnode.InnerText, out V val)) dict.Add(key, val); } }
-
@hungrier said in Serialization in .NET 2.0:
serialize and deserialize an IDictionary<string, string> to XML or JSON
Is that all you're ever going to (de)serialize? Because that's pretty easy to do by hand.
-
@anonymous234 said in Serialization in .NET 2.0:
by hand
-
@anonymous234 said in Serialization in .NET 2.0:
@hungrier said in Serialization in .NET 2.0:
serialize and deserialize an IDictionary<string, string> to XML or JSON
Is that all you're ever going to (de)serialize? Because that's pretty easy to do by hand.
Turns out it's even easier to do something else by hand
-
@hungrier said in Serialization in .NET 2.0:
That's true, and my current implementation basically just relies on not having any key/value boundaries appear in the text with no guarantee of what happens if they get in there.
There's two tips that can help fix that problem without having to actually do it the right way.
- Add some simple checks:
if (key.Contains(separatorCharacter)) throw new Exception("Don't use semicolons in the values pls")
. It's better than just messing up the data. - Use an obscure character that will never appear in real strings. You can use ASCII 0x1E "Record Separator" and pretend you're doing things correctly. The downside is that it looks ugly in text editors (), and can't be input by hand. So if you prefer, just use any unicode printable character you like! I recommend the poop emoji 💩.
Or you could use length-prefixed strings. Trivial to encode and decode, no messy escape characters, but can't be edited by hand.
Take this advice from the person who somehow ended up implementing three different custom encodings for messages in my last project (I'm not proud of that).
- Add some simple checks:
-
@anonymous234 My implementation is pretty much like this:
## myPlugin key:whatever all the stuff goes here as long as the lines don't start with the key or end value boundary strings, it should be fine ## myPlugin end
-
@anonymous234 said in Serialization in .NET 2.0:
Or you could use length-prefixed strings. Trivial to encode and decode, no messy escape characters, but can't be edited by hand.
Unless your length encodings themselves are in text (along with a terminator of your choice). Then PITA, but possible to edit by hand.