-1

I am trying to write a correct config file but I think I am confusing a couple of definitions. The final purpose is to redirect the users depending on their roles to the correct page.

Questions:

  • A nested element with multiple tags is not a ConfigurationElementCollection?
  • A single element is not a configuration element?

If that is correct, which is my error on the code below?

Here is my example, on my webconfig I wrote this:

<configSections>
        <section name="adminSecurityConfig" type="Web.Portal.Authentication.ViewModels.RoleConfiguration.AdminSecuritySection" />
</configSections>

<!--Roles for Web Portals and a link to an external file-->
<adminSecurityConfig configSource="AdminSecurity.xml" />

My AdminSecurity.xml file looks like the one below:

<?xml version="1.0" encoding="utf-8" ?>
<adminSecurityConfig>
  <role name="Employee">
    <redirectUrl src="www.google.com"></redirectUrl>
    <redirectUrl src="www.yahoo.com"></redirectUrl>
    <redirectUrl src="www.amazon.com"></redirectUrl>
  </role>
  <role name="Member">
    <redirectUrl src="www.yahoo.com"></redirectUrl>
  </role>
  <role name="Group Administrator">
  </role>
</adminSecurityConfig>

I have a helper to use the ConfigSection

public class ConfigurationRoleManager
{
    public const string seccionName = "adminSecurityConfig";

    public static AdminSecuritySection GetConfig()
    {
        return (AdminSecuritySection)ConfigurationManager.GetSection(seccionName);
    }
}

Also I have a couple of classes to have access to the elements in the xml. I am using -> to denote Contains on the below string

AdminSecuritySection -> RoleCollection -> RoleElement(with name property for the Role) -> UrlElementCollection -> UrlElement(with the source for the redirect)

Here are the classes:

  • AdminSecuritySection

    public class AdminSecuritySection : ConfigurationSection
    {
        [ConfigurationProperty("role", IsDefaultCollection = false)]
        ConfigurationCollection(typeof(RoleCollection))]
        public RoleCollection Roles
        {
            get
            {
                return this["role"] as RoleCollection ?? new RoleCollection();
            }
            set { this["role"] = value; }
        }
    }
    
  • RoleCollection

    public class RoleCollection : ConfigurationElementCollection
    {
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.BasicMap;
            }
        }
    
        protected override ConfigurationElement CreateNewElement()
        {
            return new RoleElement();
        }
    
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((RoleElement)element).Name;
        }
    
        protected override string ElementName
        {
            get { return "role"; }
        }
    
        public void Add(RoleElement element)
        {
            base.BaseAdd(element);
        }
    
        public void Remove(RoleElement element)
        {
            base.BaseRemove(element);
        }
    
        public RoleElement this[string name]
        {
            get
            {
                foreach (var item in this)
                {
                    if ((item as RoleElement).Name == name)
                        return item as RoleElement;
                }
    
                return null;
            }
        }
    }
    
  • RoleElement

    public class RoleElement : ConfigurationElement
    {
        [ConfigurationProperty("redirectUrl", IsDefaultCollection = false)]
        [ConfigurationCollection(typeof(UrlElementCollection))]
        public UrlElementCollection Urls
        {
            get { return this["redirectUrl"] as UrlElementCollection ?? new UrlElementCollection(); }
            set { this["redirectUrl"] = value; }
        }
    
        [ConfigurationProperty("name", IsRequired = true)]
        public string Name
        {
            get { return (string)this["name"]; }
            set { this["name"] = value; }
        }
    }
    
  • UrlElementCollection

    public class UrlElementCollection : ConfigurationElementCollection
    {
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.BasicMap;
            }
        }
    
        protected override string ElementName
        {
            get
            {
                return "redirectUrl";
            }
        }
    
        protected override ConfigurationElement CreateNewElement()
        {
            return new UrlElement();
        }
    
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((UrlElement)element).Source;
        }
    
        public void Add(UrlElement element)
        {
            this.BaseAdd(element);
        }
    
        public void Remove(UrlElement element)
        {
            this.BaseRemove(element);
        }
    
        public UrlElement this[string source]
        {
            get
            {
                foreach (var item in this)
                {
                    if ((item as UrlElement).Source == source)
                        return item as UrlElement;
                }
    
                return null;
            }
        }
    }
    
  • UrlElement

    public class UrlElement : ConfigurationElement
    {
        [ConfigurationProperty("src", IsRequired = true)]
        public string Source
        {
            get { return (string)this["src"]; }
            set { this["src"] = value; }
        }
    }
    

At the end when I am trying to run it this error appears:

enter image description here

Zinov
  • 3,817
  • 5
  • 36
  • 70

1 Answers1

1

Looks like your RoleCollection and RoleElement both are having same name i.e. role. That may be confusing. When it encounters role tag it is treating as role collection which doesnt have name attribute. Change RoleCollection name to roles and xml structure like below.

<?xml version="1.0" encoding="utf-8" ?>
  <adminSecurityConfig>
    <roles>
     <role name="Employee">
        <redirectUrl src="www.google.com"></redirectUrl>
        <redirectUrl src="www.yahoo.com"></redirectUrl>
        <redirectUrl src="www.amazon.com"></redirectUrl>
     </role>
     <role name="Member">
        <redirectUrl src="www.yahoo.com"></redirectUrl>
     </role>
     <role name="Group Administrator">
     </role>
   </roles>
  </adminSecurityConfig>
Pankaj Kapare
  • 7,486
  • 5
  • 40
  • 56
  • but the name roles in plural is never set on code. Actually is throwing this exception if I add that "Unrecognized element 'roles'" – Zinov Jan 21 '15 at 20:40
  • 1
    Probably this link may be helpful. http://stackoverflow.com/questions/10958054/how-to-create-a-configuration-section-that-contains-a-collection-of-collections – Pankaj Kapare Jan 21 '15 at 20:54