5

所以我有一個配置節/ ConfigurationElementCollection中有這樣的配置:如何將TypeConverters與ConfigurationSection一起使用?

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

很顯然,我需要一個類型轉換器,它實際東西(而不是這個空殼):

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

如何建立一個類型轉換器,將允許類型的便利着想從/到字符串的rsion?我試過使用MSDN的例子,但我不斷收到錯誤信息:

TypeConverter無法從System.String轉換。

本質上,它是如何設置的,以便它可以與任何ConfigurationSection試圖做的事情一起工作?

回答

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

您不需要手動獲取'TypeConverter'。刪除'TypeDescriptor.GetConverter ...'。正如你所做的那樣,將TypeConverter分配給屬性或鍵入本身就足夠了。 – 2011-05-09 18:51:48

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

EDITED

您還需要重寫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; 
} 
+0

不起作用。我仍然收到錯誤消息:屬性'mimeFormat'的值不能被解析。錯誤是:TypeConverter無法從System.String轉換。 – 2011-05-09 17:20:03

2

試試這個:

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

} 
+0

不起作用。我仍然收到錯誤消息:屬性'mimeFormat'的值不能被解析。錯誤是:TypeConverter無法從System.String轉換。 – 2011-05-09 17:23:58

+0

@David Murdoch,我已更新。上面的代碼適合我。 – 2011-05-09 17:30:13

+0

我意識到我忽略了一條重要的信息;實際上我在ConfigurationElement的構造函數中設置了ConfigurationProperties。我正在編輯我的問題來反映這一點。 – 2011-05-09 17:35:01

1

你可以把TypeConverterAttribute的屬性來告訴串行如何處理它。

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