5

所以我有一个 ConfigurationSection/ConfigurationElementCollection,它的配置如下:

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

以下是我处理 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];
    }
}

显然我需要一个真正做某事的 TypeConverter(而不是这个空壳):

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

如何设置允许从/到字符串的类型转换的 TypeConverter?我尝试使用 MSDN 示例,但不断收到错误消息:

TypeConverter 无法从 System.String 转换。

从本质上讲,如何设置它以便它可以与 ConfigurationSection 尝试做的任何事情一起工作?

4

4 回答 4

4

您可以将 TypeConverterAttribute 放在属性上,以告诉序列化程序如何处理它。

[TypeConverter(typeof(MimeFormatConverter))]
[ConfigurationProperty("mimeFormat", IsRequired = true)]
public MimeFormat MimeFormat
{
    get { return (MimeFormat)base[_mimeFormat]; }
}
于 2014-10-15T16:49:02.647 回答
3

试试这个:

测试节.cs

public class TestSection : ConfigurationSection
{

    private static readonly ConfigurationProperty sFooProperty = new ConfigurationProperty("Foo",
                                                                                          typeof(Foo),
                                                                                          null,
                                                                                          new FooTypeConverter(),
                                                                                          null,
                                                                                          ConfigurationPropertyOptions.None);

    public static readonly ConfigurationPropertyCollection sProperties = new ConfigurationPropertyCollection();

    static TestSection()
    {
        sProperties.Add(sFooProperty);
    }

    public Foo Foo
    {
        get { return (Foo)this[sFooProperty]; }
        set { this[sFooProperty] = value; }
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return sProperties; }
    }

}

Foo.cs

public class Foo
{

    public string First { get; set; }
    public string Second { get; set; }

    public override string ToString()
    {
        return First + ',' + Second;
    }

}

FooTypeConverter.cs

public class FooTypeConverter : TypeConverter
{

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return (sourceType == typeof(string));
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string val = value as string;

        if (val != null)
        {
            string[] parts = val.Split(',');

            if (parts.Length != 2)
            {
                // Throw an exception
            }

            return new Foo { First = parts[0], Second = parts[1] };
        }

        return null;
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return (destinationType == typeof(string));
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        Foo val = value as Foo;

        if (val != null)
            return val.ToString();

        return null;
    }

}
于 2011-05-09T17:04:16.173 回答
1

我想到了。这是解决方案:

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;
    }
}
于 2011-05-09T18:14:05.917 回答
0

从这一点开始,您必须在 ConvertTo 和 ConvertFrom 方法中创建转换部分

public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value ) {
  if ( value == null )
    return null;

  try {
    if ( value is string ) {
      string s = (string)value;

      // here is where you look at the string to figure out the MimeFormat
      // like so....
      return new MimeFormat( s );
    }


  throw new NotSupportedException( NotSupportedException( value.GetType(), typeof(MimeFormat) );
}

public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType ) {
  if ( value == null )
    return null;

  MimeFormat p = (MimeFormat)value;
  if ( destinationType == typeof( String ) )
    return p.ToString();

  throw new NotSupportedException( NotSupportedException( typeof(MimeFormat), destinationType ) );
}

已编辑

您还需要重写 CanConvert 函数。

public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) {
  if ( sourceType == typeof( string ) )
    return true;
  return false;
}

public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType ) {
  if ( destinationType == typeof( string ) )
    return true;
  return false;
}
于 2011-05-09T16:59:24.753 回答