3
\$\begingroup\$

I am working on asp.net/MVC and I need to read a value from my web.config file. Splitting the list into multiple keys is not an option.

<add key="DepartAssign" value="Depart1:PersonAssignTo1; Depart2:PersonAssignTo2"/>

I handled the problem by doing the following (which I am sure that there is a better approach)

public List<string> departmentList = new List<string>();
public List<string> assignedtoList = new List<string>();
public string[] pair = ConfigurationManager.AppSettings["DepartAssign"].Split(';');
foreach (string s in pair)
{
     departmentList.Add(s.Split(':').First()); //add the department to the list
     assignedtoList.Add(s.Split(':').Last()); //add the assignedto to the list
 }

and of course, I would be able to match the department with the assigned person by using the same index. Not really the cleanest approach but it works for now.

any way to make this code better?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Wouldn't it be better if you used Dictionary<string, string> instead of two Lists? \$\endgroup\$ – svick Sep 5 '12 at 21:57
2
\$\begingroup\$

You could create your own custom section in your config file.

First define what each record looks like:

public class Department : ConfigurationSection
{
    [ConfigurationProperty("name", IsRequired = true)]
    public string Name
    {
        get { return (string)this["name"]; }
        set { this["name"] = value; }
    }

    [ConfigurationProperty("assignee", IsRequired = true)]
    public string Assignee
    {
        get { return (string)this["assignee"]; }
        set { this["assignee"] = value; }
    }
}

Define the a collection so the framework can work with your section

public class DepartmentCollection : ConfigurationElementCollection
{
    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }

    protected override string ElementName
    {
        get { return "Department"; }
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return new ConfigurationPropertyCollection(); }
    }

    public Department this[int index]
    {
        get { return (Department) BaseGet(index); }
        set
        {
            if (BaseGet(index) != null)
            {
                BaseRemoveAt(index);
            }
            base.BaseAdd(index, value);
        }
    }

    public Department this[string name]
    {
        get { return (Department) BaseGet(name); }
    }

    public void Add(Department item)
    {
        base.BaseAdd(item);
    }

    public void Remove(Department item)
    {
        BaseRemove(item);
    }

    public void RemoveAt(int index)
    {
        BaseRemoveAt(index);
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new Department();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return (element as Department).Name;
    }
}

Define what the list looks like

public class DepartmentList : ConfigurationSection
{
    private static readonly ConfigurationPropertyCollection DepartmentListProperties;
    private static readonly ConfigurationProperty DepartmentProperty;

    static DepartmentList()
    {
        DepartmentProperty = new ConfigurationProperty(
            "",
            typeof (DepartmentCollection),
            null,
            ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsDefaultCollection
            );

        DepartmentListProperties = new ConfigurationPropertyCollection
                                       {
                                           DepartmentProperty
                                       };
    }

    public DepartmentCollection Departments
    {
        get { return (DepartmentCollection) base[DepartmentProperty]; }
        set { base[DepartmentProperty] = value; }
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return DepartmentListProperties; }
    }
}

Now, in your .config file specify the new type:

<configSections>
    <section name="DepartmentAssigneeMapping" type="DatabaseCleanup.DepartmentList, DatabaseCleanup, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>

and add your section

<DepartmentAssigneeMapping>
    <Department name="Depart1" assignee="PersonAssignTo1" />
    <Department name="Depart2" assignee="PersonAssignTo2" />
</DepartmentAssigneeMapping>

Now, in your class:

public List<string> departmentList;
public List<string> assignedtoList;

var mappings = (DepartmentList) ConfigurationManager.GetSection("DepartmentAssigneeMapping");

departmentList = (
    from Department department in mappings.Departments 
    select department.Name).ToList();
assignedtoList = (
    from Department department in mappings.Departments 
    select department.Assignee).ToList();

Your class is much nicer, and the config is way cleaner.

This is fully tested, and the results you are looking for are replicated.

\$\endgroup\$
2
  • \$\begingroup\$ interesting. But why not make the result a dictionary with Name as key and Assignee as value? (using ToDictionary once instead of ToList twice) \$\endgroup\$ – Adam Sep 6 '12 at 8:48
  • \$\begingroup\$ Didn't think of doing it that way because the OP said 2 lists were needed. There's no reason you can't make it into a dictionary and pull the keys and values into separate lists I guess. \$\endgroup\$ – Jeff Vanzella Sep 6 '12 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.