how to convert NameValueCollection to JSON string?

One way to serialize NameValueCollection is by first converting it to Dictionary and then serialize the Dictionary. To convert to dictionary:

thenvc.AllKeys.ToDictionary(k => k, k => thenvc[k]);

If you need to do the conversion frequently, you can also create an extension method to NameValueCollection:

public static class NVCExtender
{
    public static IDictionary<string, string> ToDictionary(
                                        this NameValueCollection source)
    {
        return source.AllKeys.ToDictionary(k => k, k => source[k]);
    }
}

so you can do the conversion in one line like this:

NameValueCollection Data = new NameValueCollection();
Data.Add("Foo", "baa");

var dict = Data.ToDictionary();

Then you can serialize the dictionary:

var json = new JavaScriptSerializer().Serialize(dict);
// you get {"Foo":"baa"}

But NameValueCollection can have multiple values for one key, for example:

NameValueCollection Data = new NameValueCollection();
Data.Add("Foo", "baa");
Data.Add("Foo", "again?");

If you serialize this you will get {"Foo":"baa,again?"}.

You can modify the converter to produce IDictionary<string, string[]> instead:

public static IDictionary<string, string[]> ToDictionary(
                                    this NameValueCollection source)
{
    return source.AllKeys.ToDictionary(k => k, k => source.GetValues(k));
}

So you can get serialized value like this: {"Foo":["baa","again?"]}.


NameValueCollection isn't an IDictionary, so the JavaScriptSerializer cannot serialize it as you expect directly. You'll need to first convert it into a dictionary, then serialize it.

Update: following questions regarding multiple values per key, the call to nvc[key] will simply return them separated by a comma, which may be ok. If not, one can always call GetValues and decide what to do with the values appropriately. Updated the code below to show one possible way.

public class StackOverflow_7003740
{
    static Dictionary<string, object> NvcToDictionary(NameValueCollection nvc, bool handleMultipleValuesPerKey)
    {
        var result = new Dictionary<string, object>();
        foreach (string key in nvc.Keys)
        {
            if (handleMultipleValuesPerKey)
            {
                string[] values = nvc.GetValues(key);
                if (values.Length == 1)
                {
                    result.Add(key, values[0]);
                }
                else
                {
                    result.Add(key, values);
                }
            }
            else
            {
                result.Add(key, nvc[key]);
            }
        }

        return result;
    }

    public static void Test()
    {
        NameValueCollection nvc = new NameValueCollection();
        nvc.Add("foo", "bar");
        nvc.Add("multiple", "first");
        nvc.Add("multiple", "second");

        foreach (var handleMultipleValuesPerKey in new bool[] { false, true })
        {
            if (handleMultipleValuesPerKey)
            {
                Console.WriteLine("Using special handling for multiple values per key");
            }
            var dict = NvcToDictionary(nvc, handleMultipleValuesPerKey);
            string json = new JavaScriptSerializer().Serialize(dict);
            Console.WriteLine(json);
            Console.WriteLine();
        }
    }
}