Question

I have read a nice introduction on the topic on CodeProject and found an interesting answer here at stack*overflow*, but it seems my own attempts at recreating what I read fails. I guess I missed something but can't find out what.

The following exception makes me think, maybe there are some restrictions in how I can nest configuration-sections/-elements/-elementcollections that I have not properly obeyed.

Would be lovely if anyone could explain how to properly do it (or point to thorough and easy to read explanations) and maybe even point out what I did wrong in my case!

Thanks a lot in advance!

The Exception I get is:

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately. 

Parser Error Message: Unrecognized element 'LoggerRegistration'.

Source Error: 

Line 29:     <LoggerRegistrations>
Line 30:         
Line 31:       <LoggerRegistration Name="Fachlich">
Line 32:         <LogMappers>
Line 33:           <LogMapper  Name="Standard"

Source File: C:\P\INT_TRWeb\DEV\ITERGO.Tarifrechner\ITERGO.TR.WebUi\web.config    Line: 31 

the corresponding excerpt from my web.config:

<configuration>
    <configSections>
        <section    Name="LoggerSettings" 
                    Type="LoggingTest.Core.LoggingSettings, LoggingTest.Core, Version=1.0.0.0, Culture=neutral"/>
    </configSections>

    <LoggerSettings    
        ServerId = "..."
        ServerName = "..."
        StageId = "..."
        WebId = "..."
        MandantId = "..."
        PartnerId = "..."
        ExternalPartnerId = "..."
        AppName = "...">

        <LoggerRegistrations>

            <LoggerRegistration Name="Fachlich">
                <LogMappers>
                    <LogMapper  Name="Standard"
                                MapperType="Logging.Core.LogMapperImpl.TrLogMapper"
                                MapperSubType="Logging.Entity.StandardLogEntry"
                                LogLevel="Information" />
                    <LogMapper  Name="Statistik"
                                MapperType="Logging.Core.LogMapperImpl.TrLogMapper"
                                MapperSubType="Logging.Entity.StatisticalLogEntry"
                                LogLevel="Information" />
                 </LogMappers>
            </LoggerRegistration>

            <LoggerRegistration Name="Technisch">
                <LogMappers>
                    <LogMapper  Name="Standard"
                                MapperType="Logging.Core.LogMapperImpl.TrLogMapper"
                                MapperSubType="Logging.Entity.StandardLogEntry"
                                LogLevel="Warning" />
                    <LogMapper  Name="Statistik"
                                MapperType="Logging.Core.LogMapperImpl.TrLogMapper"
                                MapperSubType="Logging.Entity.StatisticalLogEntry"
                                LogLevel="Information" />
                    <LogMapper  Name="EntLib"
                                MapperType="Logging.Core.LogMapperImpl.EntLibMapper"
                                MapperSubType="none" />
                </LogMappers>
            </LoggerRegistration>

        </LoggerRegistrations>
    </LoggerSettings>
</configuration>

and here are the corresponding classes:

public class LoggerSettings : ConfigurationSection
{

    [ConfigurationProperty("ServerId", DefaultValue = "DevLocalhost")]
    public string ServerId 
    { 
        get { return (string) this["ServerId"]; }
        set { this["ServerId"] = value; }
    }

    [ConfigurationProperty("ServerName", DefaultValue = null)]
    public string ServerName
    { 
        get { return (string) this["ServerName"] ?? System.Environment.MachineName; }
        set { this["ServerName"] = value ?? System.Environment.MachineName; }
    }

    [ConfigurationProperty("StageId", DefaultValue = "DevLocal")]
    public string StageId
    { 
        get { return (string) this["StageId"]; }
        set { this["StageId"] = value; }
    }

    [ConfigurationProperty("WebId", DefaultValue = null)]
    public string WebId
    { 
        get { return (string) this["WebId"] ?? System.Environment.MachineName; }
        set { this["WebId"] = value ?? System.Environment.MachineName; }
    }

    [ConfigurationProperty("MandantId", DefaultValue = "n/a")]
    public string MandantId
    { 
        get { return (string) this["MandantId"]; }
        set { this["MandantId"] = value; }
    }

    [ConfigurationProperty("PartnerId", DefaultValue = "n/a")]
    public string PartnerId
    { 
        get { return (string) this["PartnerId"]; }
        set { this["PartnerId"] = value; }
    }

    [ConfigurationProperty("ExternalPartnerId", DefaultValue = "n/a")]
    public string ExternalPartnerId
    { 
        get { return (string) this["ExternalPartnerId"]; }
        set { this["ExternalPartnerId"] = value; }
    }

    [ConfigurationProperty("AppName", DefaultValue = "n/a")]
    public string AppName
    { 
        get { return (string) this["AppName"]; }
        set { this["AppName"] = value; }
    }

    [ConfigurationProperty("LoggerRegistrations")]
    public LoggerRegistrationCollection LoggerRegistrations
    {
        get { return (LoggerRegistrationCollection)this["LoggerRegistrations"]; }
    }

}

[ConfigurationCollection(typeof(LoggerRegistration))]
public class LoggerRegistrationCollection : ConfigurationElementCollection
{
    public new LoggerRegistration this[string Name]
    {
        get { return (LoggerRegistration)base.BaseGet(Name); }
    }

    public LoggerRegistration this[int index]
    {
        get { return (LoggerRegistration)base.BaseGet(index); }
    }

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

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

public class LoggerRegistration : ConfigurationElement
{
    [ConfigurationProperty("Name", IsRequired=true)]
    public string Name
    {
        get { return (string)base["Name"]; }
        set { base["Name"] = value; }
    }

    [ConfigurationProperty("LogMappers")]
    public LogMapperElementCollection LogMappers
    {
        get { return (LogMapperElementCollection) this["LogMappers"]; }
    }

}


[ConfigurationCollection(typeof(LogMapperElement))]
public class LogMapperElementCollection : ConfigurationElementCollection
{
    public new LogMapperElement this[string Name]
    {
        get { return (LogMapperElement)base.BaseGet(Name); }
    }

    public LogMapperElement this[int index]
    {
        get { return (LogMapperElement)base.BaseGet(index); }
    }

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

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

public class LogMapperElement : ConfigurationElement
{
    [ConfigurationProperty("Name", IsRequired = true)]
    public string Name
    {
        get { return (string)base["Name"]; }
        set { base["Name"] = value; }
    }

    [ConfigurationProperty("MapperType", IsRequired = true)]
    public Type MapperType
    {
        get { return Type.GetType((string) base["MapperType"]); }
        set { base["MapperType"] = value.FullName; }
    }

    [ConfigurationProperty("MapperSubType", DefaultValue = null)]
    public Type MapperSubType
    {
        get { return (string) base["MapperSubType"] == "none" ? null : Type.GetType((string) base["MapperSubType"]); }
        set { base["MapperSubType"] = value != null ? value.FullName : "none"; }
    }

    [ConfigurationProperty("LogLevel", DefaultValue = LogLevel.Warning)] 
    public LogLevel LogLevel
    {
        get { return (LogLevel) Enum.Parse(typeof (LogLevel), (string) this["LogLevel"]); }
        set { this["LogLevel"] = value.ToString(); }
    }
}
Was it helpful?

Solution

Took me a while to find the problem. It seems the collections don't know which elementitems to look for in the config file. Therefore Adding an ItemName at the Collections ConfigurationCollection-Attribute will do the trick:

...
[ConfigurationCollection(typeof(LoggerRegistration), AddItemName = "LoggerRegistration")]
public class LoggerRegistrations : ConfigurationElementCollection
{
...
.
...
[ConfigurationCollection(typeof(LogMapperElement), AddItemName = "LogMapper")]
public class LogMappers : ConfigurationElementCollection
...

The ItemName must be set to the tagname used in the config file for the collections elements, and be passed via 'AddItemName="..."'

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top