Search code examples
c#.net-4.0type-conversionconfigurationsectionsystem.configuration

How can I use TypeConverters with a ConfigurationSection?


So I've got a ConfigurationSection/ConfigurationElementCollection that has a configuration like this:

<mimeFormats>
    <add mimeFormat="text/html" />
</mimeFormats>

And here is how I handle the mimeFormats:

 public class MimeFormatElement: ConfigurationElement
{
    #region Constructors
    /// <summary>
    /// Predefines the valid properties and prepares
    /// the property collection.
    /// </summary>
    static MimeFormatElement()
    {
        // Predefine properties here
        _mimeFormat = new ConfigurationProperty(
            "mimeFormat",
            typeof(MimeFormat),
            "*/*",
            ConfigurationPropertyOptions.IsRequired
        );
    }
    private static ConfigurationProperty _mimeFormat;
    private static ConfigurationPropertyCollection _properties;

    [ConfigurationProperty("mimeFormat", IsRequired = true)]
    public MimeFormat MimeFormat
    {
        get { return (MimeFormat)base[_mimeFormat]; }
    }
}

public class MimeFormat
{
    public string Format
    {
        get
        {
            return Type + "/" + SubType;
        }
    }
    public string Type;
    public string SubType;

    public MimeFormat(string mimeFormatStr)
    {
        var parts = mimeFormatStr.Split('/');
        if (parts.Length != 2)
        {
            throw new Exception("Invalid MimeFormat");
        }

        Type = parts[0];
        SubType = parts[1];
    }
}

And obviously I need a TypeConverter that actually does something (instead of this empty shell):

public class MimeFormatConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        throw new NotImplementedException();
    }
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        throw new NotImplementedException();
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        throw new NotImplementedException();
    }
}

How do I set up a TypeConverter that will allow type conversion from/to string? I've tried using the MSDN examples but I keep getting error message:

TypeConverter cannot convert from System.String.

Essentially, how can it be set up so that it will just work with whatever ConfigurationSection is trying to do?


Solution

  • I figured it out. Here is the solution:

    public class MimeFormatElement: ConfigurationElement
    {
        #region Constructors
        /// <summary>
        /// Predefines the valid properties and prepares
        /// the property collection.
        /// </summary>
        static MimeFormatElement()
        {
            // Predefine properties here
            _mimeFormat = new ConfigurationProperty(
                "mimeFormat",
                typeof(MimeFormat),
                "*/*",
                ConfigurationPropertyOptions.IsRequired
            );
    
            _properties = new ConfigurationPropertyCollection {
                _mimeFormat, _enabled
            };
        }
        private static ConfigurationProperty _mimeFormat;
        private static ConfigurationPropertyCollection _properties;
    
        [ConfigurationProperty("mimeFormat", IsRequired = true)]
        public MimeFormat MimeFormat
        {
            get { return (MimeFormat)base[_mimeFormat]; }
        }
    }
    
    /*******************************************/
    [TypeConverter(typeof(MimeFormatConverter))]
    /*******************************************/
    public class MimeFormat
    {
        public string Format
        {
            get
            {
                return Type + "/" + SubType;
            }
        }
        public string Type;
        public string SubType;
    
        public MimeFormat(string mimeFormatStr)
        {
            var parts = mimeFormatStr.Split('/');
            if (parts.Length != 2)
            {
                throw new Exception("Invalid MimeFormat");
            }
    
            Type = parts[0];
            SubType = parts[1];
        }
    }
    
    public class MimeFormatConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            return new MimeFormat((string)value);
        }
    
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(string);
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var val = (MimeFormat)value;
            return val.Type + "/" + val.SubType;
        }
    }