Hi Kosta, Thanks for the hint :-) Now I understand what ThrowOnDuplicate means - it rejects a different element. Therefore, current mono implementation has an issue that an identical element to one of the existing items actually raises an error.
I have a patch and some standalone tests for review. Atsushi Eno Konstantin Triger wrote:
Hi Atsushi,I think the implementation of ThrowOnDuplicate is correct: it indicates whether the collection throws if duplicates exist. To make this happen there should be elements with same keys but different values. But I think that your implementation of MySection is incorrect, it should be like this:public class MySection : ConfigurationSection { [ConfigurationProperty("MyElements")] public MyElementCollection MyElements { get { return (MyElementCollection)this["MyElements"]; } } } In addition, a cleaner implementation for MyElement would be this: public class MyElement : ConfigurationElement {[ConfigurationProperty("name", Options = ConfigurationPropertyOptions.IsKey)]public string Name { get { return (string)this["name"]; } } /* [ConfigurationProperty("value")] public string Value { get { return (string)this["value"]; } } */ }BTW, uncomment Value property and add some 'value' to one of your Foos. This throws on .net (did not check on mono).Regards, Kosta -----Original Message----- From: [EMAIL PROTECTED] on behalf of Atsushi Eno Sent: Fri 22/12/2006 11:03 To: mono-devel-list@lists.ximian.com Subject: [Mono-dev] ConfigurationElementCollection.ThrowOnDuplicate Hi, I have been trying to fix some web service config stuff, and noticed that ConfigurationElementCollection.ThrowOnDuplicate property behavior is somewhat different from .net (the attached example does not raise an error on .net while mono does). According to the documentation, I believe that Mono behavior is the correct behavior, but with this I find difficulty to fix web service configuration issue, so I'm tempted to find that current behavior is incorrect (and my understanding becomes wrong) ;-) So, does anyone have ideas on how this property works? Atsushi Eno
using System; using System.Configuration; public class MyElement : ConfigurationElement { public MyElement () { } [ConfigurationProperty ("name", Options = ConfigurationPropertyOptions.IsKey)] public string Name { get { return (string) this ["name"]; } } [ConfigurationProperty ("value")] public string Value { get { return (string) this ["value"]; } } } [ConfigurationCollection (typeof (MyElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] public class MyElementCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement () { return new MyElement (); } protected override object GetElementKey (ConfigurationElement e) { return ((MyElement) e).Name; } public void Add (MyElement e) { BaseAdd (e); } protected override void BaseAdd (ConfigurationElement e) { base.BaseAdd (e); } } public class MySection : ConfigurationSection { [ConfigurationProperty ("MyElements")] public MyElementCollection MyElements { get { return (MyElementCollection) this ["MyElements"]; } } } public class Driver { public static void Main () { try { MySection ms = (MySection) ConfigurationManager.GetSection ("MySection"); foreach (MyElement e in ms.MyElements) Console.WriteLine (e.Name); } catch (ConfigurationException ex) { Console.WriteLine ("Configuration error"); } } }
t38.exe.config
Description: application/xml
Configuration error
using System; using System.Configuration; public class MyElement : ConfigurationElement { public MyElement () { } [ConfigurationProperty ("name", Options = ConfigurationPropertyOptions.IsKey)] public string Name { get { return (string) this ["name"]; } } [ConfigurationProperty ("value")] public string Value { get { return (string) this ["value"]; } } } [ConfigurationCollection (typeof (MyElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] public class MyElementCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement () { return new MyElement (); } protected override object GetElementKey (ConfigurationElement e) { return ((MyElement) e).Name; } public void Add (MyElement e) { BaseAdd (e); } protected override void BaseAdd (ConfigurationElement e) { base.BaseAdd (e); } } public class MySection : ConfigurationSection { [ConfigurationProperty ("MyElements")] public MyElementCollection MyElements { get { return (MyElementCollection) this ["MyElements"]; } } } public class Driver { public static void Main () { MySection ms = (MySection) ConfigurationManager.GetSection ("MySection"); foreach (MyElement e in ms.MyElements) Console.WriteLine (e.Name); } }
t39.exe.config
Description: application/xml
Foo
Index: System.Configuration/ConfigurationElementCollection.cs =================================================================== --- System.Configuration/ConfigurationElementCollection.cs (revision 69925) +++ System.Configuration/ConfigurationElementCollection.cs (working copy) @@ -149,12 +149,17 @@ protected void BaseAdd (ConfigurationElement element, bool throwIfExists) { - if (throwIfExists && BaseIndexOf (element) != -1) - throw new ConfigurationException ("Duplicate element in collection"); + if (BaseIndexOf (element) != -1) + // there already an identical element exists. + // In such case, simply do nothing (even if + // ThrowOnDuplicate is true). + return; if (IsReadOnly ()) throw new ConfigurationErrorsException ("Collection is read only."); int old_index = IndexOfKey (GetElementKey (element)); + if (ThrowOnDuplicate && old_index >= 0) + throw new ConfigurationException ("Duplicate element in collection"); if (IsAlternate) { list.Insert (inheritedLimitIndex, element); inheritedLimitIndex++;
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list