Question

So I made a custom section handler to read information from the app-config file but when I try run it i get the following error: Object reference not set to an instance of an object.

I have been trying to fix this problem for two days now with no luck

Here is a look at my code: App - config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!-- Configuration section-handler declaration area. -->
  <configSections>
        <sectionGroup name="propertyValuesGroup">
          <section
            name="propertyValues"
            type="FlatFileTestCaseAutomater.ClaimHeaderSection,FlatFileFactory"
            allowLocation="true"
            allowDefinition="Everywhere"
          />
        </sectionGroup>
    <!-- Other <section> and <sectionGroup> elements. -->
  </configSections>

  <!-- Configuration section settings area. -->

  <propertyValuesGroup>

    <propertyValues>
      <property>
        <clear/>
      <claimHeader name="txnNo" nullable="yes" dataType="int" maxLength="20" />
      <claimHeader name="batchNo" nullable="yes" dataType="string" maxLength="20" />
      </property>
    </propertyValues>

  </propertyValuesGroup>


</configuration>

My custom section handler:

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

namespace FlatFileTestCaseAutomater
{
    class ClaimHeaderSection : ConfigurationSection
    {

        [ConfigurationProperty("claimHeader")]
        public ClaimHeaderElement ClaimHeaderProperty
        {
            get
            {
                return (ClaimHeaderElement)this["claimHeader"];
            }
            set
            { this["claimHeader"] = value; }
        }
    }





    public class ClaimHeaderElement : ConfigurationElement
    {
        [ConfigurationProperty("name", DefaultValue = "", IsRequired = true)]
        public String Name
        {
            get
            {
                return (String)this["name"];
            }
            set
            {
                this["name"] = value;
            }
        }

        [ConfigurationProperty("nullable", DefaultValue = "yes", IsRequired = true)]
        public String Nullable
        {
            get
            {
                return (String)this["nullable"];
            }
            set
            {
                this["nullable"] = value;
            }
        }

        [ConfigurationProperty("dataType", DefaultValue = "", IsRequired = true)]
        public String DataType
        {
            get
            {
                return (String)this["dataType"];
            }
            set
            {
                this["dataType"] = value;
            }
        }

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

    }

}

And calling the object:

 FlatFileTestCaseAutomater.ClaimHeaderSection config =
    (FlatFileTestCaseAutomater.ClaimHeaderSection)System.Configuration.ConfigurationManager.GetSection(
    "propertyValuesGroup/propertyValues/property/");
Was it helpful?

Solution

You are getting a null because the section path is wrong, it should be:

ClaimHeaderSection config =
(ClaimHeaderSection)System.Configuration.ConfigurationManager.GetSection(
"propertyValuesGroup/propertyValues");

But right now as you have designed the custom configuration section if you put that valid path, you will get a ConfigurationErrorsException with the message "Unrecognized element 'property'."

Based on the configuration that you posted, you want a collection of ClaimHeaderElement, but you are not defining a ConfigurationElementCollection in your custom section, instead you are defining a ConfigurationElement.

In order to work you should implement an ConfigurationElementCollection, something like this:

public class ClaimHeaderCollection : ConfigurationElementCollection 
{

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

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

    public override ConfigurationElementCollectionType CollectionType
    {
        get
        {
            return ConfigurationElementCollectionType.AddRemoveClearMap;
        }
    }
}

Now in your custom section you have to add the collection:

public class ClaimHeaderSection : ConfigurationSection
{
    [ConfigurationProperty("property", IsDefaultCollection = false)]
    [ConfigurationCollection(typeof(ClaimHeaderCollection), 
        AddItemName = "add",
        ClearItemsName = "clear",
        RemoveItemName = "remove")]
    public ClaimHeaderCollection ClaimHeaders
    {
        get
        {
            return (ClaimHeaderCollection)this["property"];
        }
        set
        { this["property"] = value; }
    }

    public static ClaimHeaderSection GetConfiguration()
    {
        return GetConfiguration("propertyValuesGroup/propertyValues");
    }

    public static ClaimHeaderSection GetConfiguration(string section) 
    {
        return ConfigurationManager.GetSection(section) as ClaimHeaderSection;
    }
}

Note that I added two static methods called GetConfiguration, this will make easier to get the configuration section:

ClaimHeaderSection config = ClaimHeaderSection.GetConfiguration();

In your config you should change the name of configuration elements from claimHeader to add, if you want xml node to be called claimHeader instead of add, you should change the AddItemName value in ConfigurationCollection attribute from add to claimHeader. I'll leave it in "add" because I put add in the attribute:

<!-- Configuration section settings area. -->
<propertyValuesGroup>
  <propertyValues>
    <property>
      <clear/>
      <add name="txnNo" nullable="yes" dataType="int" maxLength="20" />
      <add name="batchNo" nullable="yes" dataType="string" maxLength="20" />
    </property>
  </propertyValues>
</propertyValuesGroup>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top