tags:

views:

1061

answers:

5

I've created a user scoped setting with the type "System.Collections.Specialized.StringDictionary". Whenever I open the local settings, I can see it in the config, but it's empty.

I have other user settings that save correctly, but this dictionary doesn't seem to be saving at all.

Is there something I need to do in order to get a dictionary to save?

+1  A: 

If you're setting it from code, are you remembering to call Settings.Save()?

Edit: Boy am I dumb, I just remembered I had the same problem myself and labored over it for hours. The problem is that the Dictionary doesn't serialize to XML (even though it really should). You have two options. You can specify your own serialization methods for the dictionary, or you can cheat.

If you don't care about being able to read/edit the values in the XML, you can add a [SettingSerializeAs(SettingsSerializeAs.Binary)] attribute to the setting. Gets the job done, but it's the quick-and-dirty approach.

lc
Yes, I'm calling Save(). All my other settings are saving correctly except my StringDictionary.
+1  A: 

I don't know about any specific issues or workarounds for working with StringDictionary in the settings, but perhaps side-step the issue and just work with a string? You could serialize the data as xml, or (perhaps simpler) just a key/value delimited string? Note that DbConnectionStringBuilder offers a simple way of doing this (as below).

The tokenized string is "abc=def;ghi=jkl", but it will automatically handle escaping rules etc for more complex data. Worth a try?

using System;
using System.Collections.Specialized;
using System.Data.Common;
public static class Program
{
    static void Main()
    {
        StringDictionary lookup = new StringDictionary();
        lookup.Add("abc", "def");
        lookup.Add("ghi", "jkl");

        string foo = Serialize(lookup);
        Console.WriteLine(foo);

        StringDictionary bar = Deserialize(foo);
        foreach (string key in bar.Keys)
        {
            Console.WriteLine("{0}={1}", key, bar[key]);
        }
    }
    public static string Serialize(StringDictionary data)
    {
        if(data == null) return null; // GIGO
        DbConnectionStringBuilder db = new DbConnectionStringBuilder();
        foreach (string key in data.Keys)
        {
            db[key] = data[key];
        }
        return db.ConnectionString;
    }
    public static StringDictionary Deserialize(string data)
    {
        if (data == null) return null; // GIGO
        DbConnectionStringBuilder db = new DbConnectionStringBuilder();
        StringDictionary lookup = new StringDictionary();
        db.ConnectionString = data;
        foreach (string key in db.Keys)
        {
            lookup[key] = Convert.ToString(db[key]);
        }
        return lookup;
    }

}
Marc Gravell
+1  A: 

Dictionary is not saved because there is no implement XmlSerializable. I'm not sure but it seems to me.

mykhaylo
A: 

Correct! To make a StringDictionary serializable, place [SettingsSerializeAs(SettingsSerializeAs.Binary)] in the Settings.Designer.cs file. What a quick and great trick. Thank you so much for posting this solution.

A: 

how would you do that in vb.net?

could you post an example of the Settings.Designer.cs file or even better an example of a Settings.Designer.vb file?