2

i have custom config section like

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="DBConfiguration" type="NewSQLExecuter.DBConfigurationSection, NewSQLExecuter"/>
    </configSections>

    <DBConfiguration>
        <Items>
            <add servername="192.168.50.2\db1" dbname="test1" userid="sa" password="2222m@n" countrycode="GB" />
            <add servername="192.168.60.2\db2" dbname="test2" userid="sa" password="22222n" countrycode="US" />
            <add servername="192.168.70.2\db3" dbname="test3" userid="sa" password="3333" countrycode="DE" />
        </Items>
    </DBConfiguration>

</configuration>

i have written a class which read data from custom config section...the class code as follows.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace NewSQLExecuter
{

    public class DBConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("Items")]
        public ItemsCollection Items
        {
            get { return ((ItemsCollection)(base["Items"])); }
        }
    }

    [ConfigurationCollection(typeof(ItemsElement))]
    public class ItemsCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ItemsElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ItemsElement)(element)).CountryCode;
        }

        public ItemsElement this[int idx]
        {
            get
            {
                return (ItemsElement)BaseGet(idx);
            }
        }
    }

    public class ItemsElement : ConfigurationElement
    {
        [ConfigurationProperty("servername", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string ServerName
        {
            get
            {
                return ((string)(base["servername"]));
            }
            set
            {
                base["servername"] = value;
            }
        }

        [ConfigurationProperty("dbname", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string DBName
        {
            get
            {
                return ((string)(base["dbname"]));
            }
            set
            {
                base["dbname"] = value;
            }
        }

        [ConfigurationProperty("userid", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string UserID
        {
            get
            {
                return ((string)(base["userid"]));
            }
            set
            {
                base["userid"] = value;
            }
        }

        [ConfigurationProperty("password", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Password
        {
            get
            {
                return ((string)(base["password"]));
            }
            set
            {
                base["password"] = value;
            }
        }

        [ConfigurationProperty("countrycode", DefaultValue = "", IsKey = true, IsRequired = true)]
        public string CountryCode
        {
            get
            {
                return ((string)(base["countrycode"]));
            }
            set
            {
                base["countrycode"] = value;
            }
        }
    }
}

this way i iterate the custom config data and get the value

DBConfigurationSection section = (DBConfigurationSection)ConfigurationManager.GetSection("DBConfiguration");

if (section != null)
{
    DateTime satrt = DateTime.Now;

    for (int i = 0; i <= section.Items.Count - 1; i++)
    {
        var country = section.Items[i].CountryCode; ;
        var constring = string.Format("{0}{1}{2}{3}", "UID=" + section.Items[i].UserID, ";PWD=" + section.Items[i].Password, 
                                    ";Server=" + section.Items[i].ServerName, ";Database=" + section.Items[i].DBName); 
        dicList.Add(country, constring);
    }
}

the code works fine but i want to add one more feature like search any config data by any key value like

if(section.key.userid=="joy")
{
    string pwd=section.key.password
}

So guide me how could add search functionality into my class. it would be nice if i could use LINQ to search for any custom config data. so please guide me thanks.

Getting error to handle two custom config section in app.config file

my app.config file look like

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="DBConfiguration" type="CSRAssistant.DBConfigurationSection, CSRAssistant"/>
        <section name="LoginConfiguration" type="CSRAssistant.LoginConfigurationSection, CSRAssistant"/>
    </configSections>

    <DBConfiguration>
        <add servername="dbname" dbname="BBAJobBoardForGB" userid="sa" password="222" countrycode="GBR" />
        <add servername="db2" dbname="BBAJobBoardForUS" userid="sa" password="swww" countrycode="USA" />

    </DBConfiguration>

    <LoginConfiguration>
        <add UserName="ww" Pwd="ww" Country="GBR"/>
        <add UserName="ss" Pwd="ss"  Country="USA"/>
        <add UserName="dd" Pwd="dd"  Country="CAD"/>
    </LoginConfiguration>
    <appSettings>
        <add key="MailID" value="tridip@bba-reman.com" />
    </appSettings>

    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0"/>
        <requiredRuntime version="v4.0.20506"/>
    </startup>

</configuration>

to handle two section my code follows as

namespace CSRAssistant
{

    public class DBConfigurationSection : ConfigurationSection
    {
        //[ConfigurationProperty("Items")]
        //public ItemsCollection Items
        //{
        //    get { return ((ItemsCollection)(base["Items"])); }
        //}

        [ConfigurationProperty("", IsDefaultCollection = true)]
        public ItemsCollection Items 
        { 
            get 
            { 
                return ((ItemsCollection)(base[""])); 
            } 
        }
    }

    [ConfigurationCollection(typeof(ItemsElement))]
    public class ItemsCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ItemsElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ItemsElement)(element)).CountryCode;
        }

        public ItemsElement this[int idx]
        {
            get
            {
                return (ItemsElement)BaseGet(idx);
            }
        }
    }

    public class ItemsElement : ConfigurationElement
    {
        [ConfigurationProperty("servername", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string ServerName
        {
            get
            {
                return ((string)(base["servername"]));
            }
            set
            {
                base["servername"] = value;
            }
        }

        [ConfigurationProperty("dbname", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string DBName
        {
            get
            {
                return ((string)(base["dbname"]));
            }
            set
            {
                base["dbname"] = value;
            }
        }

        [ConfigurationProperty("userid", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string UserID
        {
            get
            {
                return ((string)(base["userid"]));
            }
            set
            {
                base["userid"] = value;
            }
        }

        [ConfigurationProperty("password", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Password
        {
            get
            {
                return ((string)(base["password"]));
            }
            set
            {
                base["password"] = value;
            }
        }

        [ConfigurationProperty("countrycode", DefaultValue = "", IsKey = true, IsRequired = true)]
        public string CountryCode
        {
            get
            {
                return ((string)(base["countrycode"]));
            }
            set
            {
                base["countrycode"] = value;
            }
        }
    }

    public class LoginConfigurationSection : ConfigurationSection
    {
        //[ConfigurationProperty("Items")]
        //public ItemsCollection Items
        //{
        //    get { return ((ItemsCollection)(base["Items"])); }
        //}

        [ConfigurationProperty("", IsDefaultCollection = true)]
        public ItemsCollection Items
        {
            get
            {
                return ((ItemsCollection)(base[""]));
            }
        }
    }


    public class LoginElement : ConfigurationElement
    {
        [ConfigurationProperty("UserName", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string UserName
        {
            get
            {
                return ((string)(base["UserName"]));
            }
            set
            {
                base["UserName"] = value;
            }
        }

        [ConfigurationProperty("Pwd", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Pwd
        {
            get
            {
                return ((string)(base["Pwd"]));
            }
            set
            {
                base["Pwd"] = value;
            }
        }

        [ConfigurationProperty("Country", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Country
        {
            get
            {
                return ((string)(base["Country"]));
            }
            set
            {
                base["Country"] = value;
            }
        }

    }
}

read the two custom config setting like this way

string joyPassword = "";
            LoginConfigurationSection LoginConfigurationSection = (LoginConfigurationSection)ConfigurationManager.GetSection("LoginConfiguration");
            if (LoginConfigurationSection != null)
            {
                var UserCredentials = LoginConfigurationSection.Items
                                    .Cast<LoginElement>()
                                    .FirstOrDefault(_element => _element.UserName == "razi");

                if (UserCredentials != null)
                    joyPassword = UserCredentials.Country;



                DBConfigurationSection section = (DBConfigurationSection)ConfigurationManager.GetSection("DBConfiguration");
                if (section != null)
                {
                    var DbConnection = section.Items
                                        .Cast<ItemsElement>()
                                        .FirstOrDefault(_element => _element.CountryCode.ToUpper() == joyPassword.ToUpper());

                    if (DbConnection != null)
                        joyPassword = DbConnection.ServerName;
                }
            }

now i am getting error like at runtime Unrecognized attribute 'UserName'. Note that attribute names are case-sensitive.

why Unrecognized attribute 'UserName' just do not understand....if possible please guide me. thanks

Mou
  • 15,673
  • 43
  • 156
  • 275
Thomas
  • 33,544
  • 126
  • 357
  • 626
  • 1
    I know this is not the kind of answer you are looking for but why don't you just read the config file as an xml? I mean it's so much easier to do that and using XDocument you can find anything and everything. – Alex Feb 05 '14 at 13:56
  • @Alex I disagree with this. I think the custom configuration system is much more friendly and easier to use than loading random xml files. The fact that it is integrated in the app/web.config workflow and that it can be loaded in a stardard way and still be contained in an external file via `configSource` is a killer feature. In my opinion, his example is a pretty good fit for a custom section and I would go exactly that way too. – julealgon Feb 05 '14 at 14:07
  • Given the question, in my opinion, the OP is dying for some LINQ functionality. Hence loading everything into an XDoc and then just getting children with foo = 'bar' seems like a sweet deal. Again this is just an opinion, I agree with you as far as workflow is concerned. It's the searching part that sucks in custom configs. – Alex Feb 05 '14 at 14:15
  • @Alex I believe it wouldn't be too much different than what I proposed to search the items with linq. Notice that since the item collection is still an `IEnumerable` you can use linq on it with relative ease. Even if you went the pure XML route, I would still advise to use a typed model and deserialize the xml into it. It would end up being pretty similar to the config section anyway, with the added con of being disconnected from the default workflow like I said before. I agree though that config sections are not always the answer, for instance if you already have the xml and models. – julealgon Feb 05 '14 at 14:21
  • 1
    IF one used a model :) ... which I rarely do for this sort of thing. Hence the added hassle of the config class makes it a far more cumbersome solution. But you are right, in the long term config class is the best way to go. For non-lazy devs that is. – Alex Feb 05 '14 at 14:25

2 Answers2

3

You could probably just do something like this:

var joyUserElement = section.Items
    .Cast<ItemsElement>()
    .FirstOrDefault(_element => _element.UserID == "joy");

if (joyUserElement != null)
    string joyPassword = joyUserElement.Password;

Does this make sense to you? I may be missing something here since this was not tested, but it should work fine.

I see you are using a normal for instead of foreach there too. Remember that the collection is IEnumerable, so you can just use a foreach with explicit typing, like this:

foreach(ItemElement element in section.Items)

Two more points I would like to add to this:

  • I would suggest you rename your element class to reflect what it actually is, for instance DbConfigurationElement instead of ItemElement. This will make the code a bit more clear in the long run.

  • You can 'hide' the <Items> tag in the xml there if it has no special meaning (which seems to be the case). If you annotate your collection property like this

.

[ConfigurationProperty("", IsDefaultCollection = true)]
public ItemsCollection Items
{
    get { return ((ItemsCollection)(base[""])); }
}

You can then write your section like this:

<DBConfiguration>
    <add servername="192.168.50.2\db1" dbname="test1" userid="sa" password="2222m@n" countrycode="GB" />
    <add servername="192.168.60.2\db2" dbname="test2" userid="sa" password="22222n" countrycode="US" />
    <add servername="192.168.70.2\db3" dbname="test3" userid="sa" password="3333" countrycode="DE" />
</DBConfiguration>

This is very useful for small, single collection config sections like yours.

julealgon
  • 7,072
  • 3
  • 32
  • 77
  • can u plzz guide me how to edit custom config data...because read is successful thanks – Thomas Feb 05 '14 at 15:01
  • i add one more section in app.config but wrote no code to handle it. so i am getting error called "Configuration system failed to initialize" so what i need to do to fix this error. please guide me. thanks – Thomas Feb 05 '14 at 15:04
  • Modifying values on the configuration system at runtime is very uncommon, but can be done like [this article suggests](http://msdn.microsoft.com/en-us/library/ms134088(v=vs.110).aspx). As for the second point, I'm not sure I understand what you are asking. If you add a config section declaration, inside `configSections`, you need that section to be present in the rest of the config xml, even if it is empty. Please elaborate more if this is not what you are seeing and perhaps create another question if it is unrelated. – julealgon Feb 05 '14 at 15:23
  • i did and now i am getting error called "Unrecognized attribute 'UserName'. Note that attribute names are case-sensitive." please i update my question and gave full source code. if possible please have a look and tell me where i made the mistake for the error encountering. thanks – Thomas Feb 05 '14 at 15:27
  • Well, that error is very simple. Notice that you are using the same `ItemCollection` for both config sections. The system is trying to parse an `ItemElement` from the inner text of the `LoginSection`, and obviously failing, since it is a `LoginElement`. You have to create another collection, similar to the first, that contains `LoginElement`s. This is why I suggested you to change the name of that collection, you see now the confusion it brings. If it was named explicitly to represent it is a DbConfiguration collection, you would probably not make this mistake. – julealgon Feb 05 '14 at 15:34
0

hi this way you can do it.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="DBConfiguration" type="CSRAssistant.DBConfigurationSection, CSRAssistant"/>
        <section name="LoginConfiguration" type="CSRAssistant.LoginConfigurationSection, CSRAssistant"/>
      </configSections>

      <DBConfiguration>
        <add servername="192.168.88.2\bbareman" dbname="BBAJobBoardForGB" userid="sa" password="8B@R5m@n" countrycode="GBR" />
        <add servername="192.168.1.2\bbareman" dbname="BBAJobBoardForUS" userid="sa" password="8B@R5m@n" countrycode="USA" />
        <add servername="192.168.2.2\bbareman" dbname="BBAJobBoardForDE" userid="sa" password="8B@R5m@n" countrycode="DEU" />
        <add servername="192.168.77.10\bbareman" dbname="BBAJobBoardForFR" userid="sa" password="8B@R5m@n" countrycode="FRA" />
        <add servername="192.168.3.2\bbareman" dbname="BBAJobBoardForIT" userid="sa" password="8B@R5m@n" countrycode="ITA" />
        <add servername="192.168.4.2\bbareman" dbname="BBAJobBoardForCA" userid="sa" password="8B@R5m@n" countrycode="CAD" />
        <add servername="192.168.55.10\bbareman" dbname="BBAJobBoardForES" userid="sa" password="8B@R5m@n" countrycode="ESP" />
      </DBConfiguration>

      <LoginConfiguration>
        <add ID="1" UserName="suanguite" Pwd="gguite" Country="GBR"/>
        <add ID="2" UserName="sujoy" Pwd="sujoyUS"  Country="USA"/>
        <add ID="3" UserName="sujoy" Pwd="sujoyCA"  Country="CAD"/>
        <add ID="4" UserName="pjasu" Pwd="pjasuDE"  Country="DEU"/>
        <add ID="5" UserName="kankana" Pwd="kankana123"  Country="ITA"/>
        <add ID="6" UserName="test" Pwd="test"  Country="IND"/>
        <add ID="7" UserName="biswajit" Pwd="biswajitES"  Country="ESP"/>
        <add ID="8" UserName="suparna" Pwd="suparna"  Country="CAD"/>
        <add ID="9" UserName="razi" Pwd="raziFR"  Country="FRA"/>
        <add ID="10" UserName="tridip" Pwd="tridip"  Country="GBR"/>
        <add ID="11" UserName="tridip" Pwd="tridip"  Country="ESP"/>
        <add ID="12" UserName="tridip" Pwd="tridip"  Country="FRA"/>
      </LoginConfiguration>
      <appSettings>
        <add key="MailID" value="tridip@bba-reman.com" />
      </appSettings>

      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0"/>
        <requiredRuntime version="v4.0.20506"/>
      </startup>

    </configuration>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace CSRAssistant
{
    public class DBConfigurationSection : ConfigurationSection
    {
        //[ConfigurationProperty("Items")]
        //public ItemsCollection Items
        //{
        //    get { return ((ItemsCollection)(base["Items"])); }
        //}

        [ConfigurationProperty("", IsDefaultCollection = true)]
        public ItemsCollection Items
        {
            get
            {
                return ((ItemsCollection)(base[""]));
            }
        }
    }

    [ConfigurationCollection(typeof(ItemsElement))]
    public class ItemsCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ItemsElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ItemsElement)(element)).CountryCode;
        }

        public ItemsElement this[int idx]
        {
            get
            {
                return (ItemsElement)BaseGet(idx);
            }
        }
    }

    public class ItemsElement : ConfigurationElement
    {
        [ConfigurationProperty("servername", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string ServerName
        {
            get
            {
                return ((string)(base["servername"]));
            }
            set
            {
                base["servername"] = value;
            }
        }

        [ConfigurationProperty("dbname", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string DBName
        {
            get
            {
                return ((string)(base["dbname"]));
            }
            set
            {
                base["dbname"] = value;
            }
        }

        [ConfigurationProperty("userid", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string UserID
        {
            get
            {
                return ((string)(base["userid"]));
            }
            set
            {
                base["userid"] = value;
            }
        }

        [ConfigurationProperty("password", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Password
        {
            get
            {
                return ((string)(base["password"]));
            }
            set
            {
                base["password"] = value;
            }
        }

        [ConfigurationProperty("countrycode", DefaultValue = "", IsKey = true, IsRequired = true)]
        public string CountryCode
        {
            get
            {
                return ((string)(base["countrycode"]));
            }
            set
            {
                base["countrycode"] = value;
            }
        }
    }


}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace CSRAssistant
{
    //****login config

    public class LoginConfigurationSection : ConfigurationSection
    {
        //[ConfigurationProperty("Items")]
        //public ItemsCollection Items
        //{
        //    get { return ((ItemsCollection)(base["Items"])); }
        //}

        [ConfigurationProperty("", IsDefaultCollection = true)]
        public LoginCollection Items
        {
            get
            {
                return ((LoginCollection)(base[""]));
            }
        }
    }

    [ConfigurationCollection(typeof(LoginElement))]
    public class LoginCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new LoginElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((LoginElement)(element)).ID;
        }

        public LoginElement this[int idx]
        {
            get
            {
                return (LoginElement)BaseGet(idx);
            }
        }
    }
    public class LoginElement : ConfigurationElement
    {
        [ConfigurationProperty("UserName", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string UserName
        {
            get
            {
                return ((string)(base["UserName"]));
            }
            set
            {
                base["UserName"] = value;
            }
        }

        [ConfigurationProperty("Pwd", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Pwd
        {
            get
            {
                return ((string)(base["Pwd"]));
            }
            set
            {
                base["Pwd"] = value;
            }
        }

        [ConfigurationProperty("Country", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string Country
        {
            get
            {
                return ((string)(base["Country"]));
            }
            set
            {
                base["Country"] = value;
            }
        }

        [ConfigurationProperty("ID", DefaultValue = "", IsKey = false, IsRequired = false)]
        public string ID
        {
            get
            {
                return ((string)(base["ID"]));
            }
            set
            {
                base["ID"] = value;
            }
        }
    }
}

calling way

private void button1_Click_1(object sender, EventArgs e)
        {
            string _country = "";
            string _ServerName = "";
            LoginConfigurationSection LoginConfigurationSection = (LoginConfigurationSection)ConfigurationManager.GetSection("LoginConfiguration");
            if (LoginConfigurationSection != null)
            {
                var UserCredentials = LoginConfigurationSection.Items
                                    .Cast<LoginElement>()
                                    .FirstOrDefault(_element => _element.UserName == "razi");

                if (UserCredentials != null)
                    _country = UserCredentials.Country;



                DBConfigurationSection section = (DBConfigurationSection)ConfigurationManager.GetSection("DBConfiguration");
                if (section != null)
                {
                    var DbConnection = section.Items
                                        .Cast<ItemsElement>()
                                        .FirstOrDefault(_element => _element.CountryCode.ToUpper() == _country.ToUpper());

                    if (DbConnection != null)
                        _ServerName = DbConnection.ServerName;
                }
            }
        }
Mou
  • 15,673
  • 43
  • 156
  • 275