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

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

Attachment: 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

Reply via email to