0

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/");
PeeHaa
  • 71,436
  • 58
  • 190
  • 262
Steve2056726
  • 457
  • 2
  • 6
  • 20
  • You didn't mention the programming language. It looks like C#. Assuming that's what it is, I suggest that you remove one of the existing tags, and replace it with the C# tag. That would drastically increase the visibility of your question, and the chances of it being answered quickly. – Eran Apr 30 '13 at 19:56

1 Answers1

1

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>
pablogq
  • 446
  • 4
  • 8
  • Thanks for the reply, so that was an obvious mistake not using configurationElementCollection, im still completely new to this , I tried to implement your code but im still getting a nullReferenceException? – Steve2056726 May 01 '13 at 17:58
  • I just try it works for me, I edited the answer because I forgot to put a little change in the config, but that wouldn't throw you a null reference exception... If you want I can post a link for you to download the little test that I just did and it is working, let me know. – pablogq May 02 '13 at 17:18
  • Thanks, I got it working, I didn't use your specific code in the end but you put me on the right track! Appreciate the help! – Steve2056726 May 02 '13 at 17:40