Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I automap namevaluecollection to a strongly typed class?

Tags:

c#

I have the configuration details of my application stored in a table like below :

SettingName                   SettingValue
--------------------          ---------------------
PostsPerPage                  10   
EmailErrors                   True
AdminEmailAddress             [email protected]

My dataaccess class say returns a namevaluecollection / keyvaluepair of settings stored in the table.

What would be best way to map the namevaluecollection /keyvaluepair to a strongly typed class like the one below that has the properties named the same as in SettingName Column.

public class Settings
{
    public int PostsPerPage{get;set;}
    public bool EmailErrors{get;set;}
    public string AdminEmailAddress{get;set;}
}
like image 329
Sam Avatar asked Feb 25 '10 22:02

Sam


People also ask

What is the use of NameValueCollection in C#?

NameValueCollection is used to store a collection of associated String keys and String values that can be accessed either with the key or with the index. It is very similar to C# HashTable, HashTable also stores data in Key , value format . NameValueCollection can hold multiple string values under a single key.

How do you make a NameValueCollection?

NameValueCollection data = new NameValueCollection() { { "key1", "value1"}, { "key2", new NameValueCollection() { { "key2sub", "value"} } }; c# namevaluecollection.

Is NameValueCollection case sensitive?

The name is case-insensitive.


2 Answers

Use reflection. In pseudo code:

Settings mySettingsClass = new Settings();
foreach (KeyValuePair<string, object> kvp in mySettings) 
{
    PropertyInfo pi = mySettingsClass.GetType().GetProperty(kvp.key, BindingFlags.Public | BindingFlags.Instance);
    if (pi != null) 
    {
        pi.SetValue(mySettingsClass, kvp.Value, null);
    }
}

Of course, if you are reading it back out of a dataReader, then you can take a slightly different approach and avoid using reflection (because the structure of the DataReader and the structure of the target object are known). Using reflection in this case is slower, but is a good way to generically map data from one item to another - basically you take the source property, see if the target property exists on the target object, and then assign the value if it does.

like image 60
slugster Avatar answered Sep 21 '22 02:09

slugster


Here's another shortcut if you have the Newtonsoft Json library in your project - you can use it as a translation mechanism. Not sure if it's all that great performance-wise, but it's very concise and simple...

assume "form" is your "NameValueCollection" object...

// convert to a string/string dictionary and remove anynulls that may have been passed in as a string "null"
var formDictionary = form.AllKeys
                     .Where(p => form[p] != "null")
                     .ToDictionary(p => p, p => form[p]);
string json = JsonConvert.SerializeObject(formDictionary);
var myObject = JsonConvert.DeserializeObject<MyClass>(json);
like image 27
C.List Avatar answered Sep 21 '22 02:09

C.List