如何将 TypeConverters 与 ConfigurationSection 一起使用?

发布于 2024-11-05 15:52:26 字数 2428 浏览 14 评论 0原文

所以我有一个 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 尝试执行的任何操作一起工作?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白鸥掠海 2024-11-12 15:52:26

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

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

You can put TypeConverterAttribute on the property to tell the serializer how to handle it.

[TypeConverter(typeof(MimeFormatConverter))]
[ConfigurationProperty("mimeFormat", IsRequired = true)]
public MimeFormat MimeFormat
{
    get { return (MimeFormat)base[_mimeFormat]; }
}
旧夏天 2024-11-12 15:52:26

试试这个:

TestSection.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;
    }

}

Try this:

TestSection.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;
    }

}
奢欲 2024-11-12 15:52:26

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

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

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;
    }
}
灼痛 2024-11-12 15:52:26

从现在起,您必须在 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;
}

From this point, you have to create the convert sections within the ConvertTo and ConvertFrom methods

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

EDITED

You also need to override the CanConvert functions as well.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文