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");
}
}
}