0

I've created a custom ConfigurationSection that includes an IP address value. To properly get the value out of the configuration file a TypeConverter was created to parse the IP address. The configuration file used for this test is as follows.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="mike" type="CustomConfigSection.SiteConfig, CustomConfigSection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </configSections>
    <mike IPAddress="192.168.0.1a" />
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

The IPAddressConverter uses a try/catch to determine if an invalid IP address was provided and couldn't be parsed. At that point an ArgumentException is thrown. Within the Open() method there is a try/catch surrounding the if (config.Sections["mike"] == null). This is the first place the configuration section is parsed and the IPAddressConverter tries to convert the configuration value.

The issue is Visual Studio claims the ArgumentException isn't handled in user code. According to the call stack, though, the exception is being thrown right at the beginning of the try block within the Open() method.

Does anyone know what is going on here? Why isn't the catch within the Open() method getting the ArgumentException?

Thank for the help.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Net;
using System.ComponentModel;

namespace CustomConfigSection
{
    public sealed class IPAddressConverter : ConfigurationConverterBase
    {
        public IPAddressConverter() { }

        public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            string ipaddress = ((string)value).ToLower();

            try
            {
                return IPAddress.Parse(ipaddress);
            }
            catch
            {
                throw new ArgumentException("The IPAddress contained invalid data.  The IPAddress provided was '" + ipaddress + "'.");
            }
        }

        public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            return value.ToString();
        }
    }

    public class SiteConfig : ConfigurationSection
    {
        private SiteConfig() { }

        #region Public Methods
        public static SiteConfig Open()
        {
            if ((object)instance == null)
            {
                Configuration config = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location);

                try
                {
                    if (config.Sections["mike"] == null)
                    {
                        instance = new SiteConfig();
                        config.Sections.Add("mike", instance);
                        config.Save(ConfigurationSaveMode.Modified);
                    }
                    else
                        instance = (SiteConfig)config.Sections["mike"];
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e.Message.ToString());
                    System.Environment.Exit(-1);
                }
            }

            return instance;
        }
        #endregion Public Methods

        #region Properties
        [ConfigurationProperty("IPAddress")]
        [TypeConverter(typeof(IPAddressConverter))]
        public IPAddress IPAddress
        {
            get { return (IPAddress)this["IPAddress"]; }
            set { this["IPAddress"] = value; }
        }
        #endregion Properties

        private static SiteConfig instance = null;
    }
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Debug.WriteLine("Before Open.");
            SiteConfig hi = SiteConfig.Open();
            System.Diagnostics.Debug.WriteLine("After Open.");

            hi.IPAddress = IPAddress.Parse("192.168.0.1");
        }
    }
}
Ryan
  • 1
  • 2
  • Even if you are not accessing the property per se, the app still parses the entire section before making it available. The parsing occurs at 'config.Sections["mike"]'. However, the exception would bubble up only when you access the IPAddress property. Does that answer your question? – StfBln Mar 17 '17 at 00:23
  • @StfBln "the exception would bubble up only when you access the IPAddress property" this doesn't seem to be the case. I added a try/catch around the ***SiteConfig.Open()*** and added a try/catch to a new line to access the IPAddress. The exception is occurring during the ***SiteConfig.Open***. It doesn't "bubble up" when access the IPAddress. Even the VisualStudio editor call stack is saying the exception is happening within the ***SiteConfig.Open*** at ***config.Section["mike"]***. When you ran the code were you finding the exception occurring at at different place? – Ryan Mar 20 '17 at 18:04
  • What I meant is that this exception is silent as it does not bubble up. However, try to access IPAddress after getting your config as in: "SiteConfig hi = SiteConfig.Open(); var test = hi.IPAddress;" Now you will get the exception. – StfBln Mar 20 '17 at 18:10
  • @StfBln The exception isn't silent. I've commented out everything in main except the ***SiteConfig hi = SiteConfig.Open()***. It fails on this method call. If this method is succeeding for you what are you using to run this code? – Ryan Mar 20 '17 at 19:23
  • I have just copy pasted your code within an empty console app and it works no problem. – StfBln Mar 20 '17 at 22:32
  • @StfBln That's frustrating. I don't like that it works for you but not me. What Visual Studio version are you using? – Ryan Mar 20 '17 at 22:55

0 Answers0