Domanda

I have looked at the related question Intellisense for custom config section problem with namespaces which describes the same problem I have. Although the solution is not working for me.

I am pasting my entire solution in here, so others also can see how the desired feature is achieved. I have followed many tutorials on custom made configuration sections and how to achieve Intellisense in config files, but none are addressing the issue I am having.

I am getting a ConfigurationErrorException:

Unrecognized attribute 'xmlns'. Note that attribute names are case-sensitive.

I don't know hot to fix it.

My custom configuration section class:

namespace CustomConfigurationExample
{
    using System.Configuration;

    public class MyConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("MyInstance")]
        public MyConfigurationElementCollection Configuration
        {
            get { return (MyConfigurationElementCollection)this["MyInstance"]; }
        }
    }

    public class MyConfigurationElement : ConfigurationElement
    {
        [ConfigurationProperty("MyEnums", IsKey = true, IsRequired = true)]
        public MyEnums MyEnums
        {
            get { return (MyEnums)base["MyEnums"]; }
        }

        [ConfigurationProperty("ConnectionAddress", IsKey = true, IsRequired = true)]
        public string ConnectionAddress
        {
            get { return (string)this["ConnectionAddress"]; }
        }

        [ConfigurationProperty("LoadBalancer", IsKey = true, IsRequired = true)]
        public bool LoadBalancer
        {
            get { return (bool)this["LoadBalancer"]; }
        }

    }

    public class MyConfigurationElementCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new MyConfigurationElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((MyConfigurationElement)element).MyEnums;
        }
    }
}

My Enums:

namespace CustomConfigurationExample
{
    public enum MyEnums
    {
        AB,
        CD,
        EF
    }
}

My App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="MyConfiguration" type="CustomConfigurationExample.MyConfiguration, CustomConfigurationExample" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <MyConfiguration xmlns="http://tempuri.org/MyConfiguration.xsd">
    <MyInstance>
      <add MyEnums="AB" LoadBalancer="true" ConnectionAddress="http://win.tendo.server:10305" />
    </MyInstance>
  </MyConfiguration>
</configuration>

My schema file:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="MyConfiguration"
    targetNamespace="http://tempuri.org/MyConfiguration.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/MyConfiguration.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="add">
    <xs:annotation>
      <xs:documentation>My configuration.</xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:attribute name="MyEnums" use="required" >
        <xs:annotation>
          <xs:documentation>MyEnums at blah blah</xs:documentation>
        </xs:annotation>
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="AB">
              <xs:annotation>
                <xs:documentation>AB</xs:documentation>
              </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="CD">
              <xs:annotation>
                <xs:documentation>CD</xs:documentation>
              </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="EF">
              <xs:annotation>
                <xs:documentation>EF</xs:documentation>
              </xs:annotation>
            </xs:enumeration>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="ConnectionAddress"></xs:attribute>
      <xs:attribute name="LoadBalancer">
        <xs:annotation>
          <xs:documentation>Loadbanlancer.</xs:documentation>
        </xs:annotation>
        <xs:simpleType>
          <xs:restriction base="xs:boolean">
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
</xs:schema>

...and at last my program.cs:

namespace CustomConfigurationExample
{
    using System.Collections;
    using System.Configuration;
    using System.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            var mySettings = new ArrayList(((MyConfiguration)ConfigurationManager.GetSection("MyConfiguration")).Configuration).Cast<MyConfigurationElement>().Select(x => new { x.MyEnums, x.LoadBalancer, x.ConnectionAddress,  }).SingleOrDefault();
        }
    }
}

Now I have the intellisense in my configuration working all fine. But I get an exception when trying to map my settings when I run my program. I can remove the 'xmlns="http://tempuri.org/MyConfiguration.xsd"' part in my '<MyConfiguration xmlns="http://tempuri.org/MyConfiguration.xsd">' in my App.config file and add the location at its physical location under properties of my App.config in the 'Schemas' and the intellisense is working and mapping as well. But then the physical location is tied to my machine, and I want the location to be relative as the schema file is part of my VS solution. I prefer to reference the file relative in my solution.

What I am missing? I suspect that I need to decorate MyConfiguration class file with a namespace and schemalocation?

È stato utile?

Soluzione

I found the problem in your code, and it ends up to be fairly simple. You need to add the xmlns tag to your MyConfiguration class like this:

public class MyConfiguration : ConfigurationSection
{
    [ConfigurationProperty("xmlns")]
    public string XmlNamespace
    {
        get
        {
            return (string)this["xmlns"];
        }
        set
        {
            this["xmlns"] = value;
        }
    }

    [ConfigurationProperty("MyInstance")]
    public MyConfigurationElementCollection Configuration
    {
        get { return (MyConfigurationElementCollection)this["MyInstance"]; }
    }
}

Then the ConfigurationManager knows how to read this.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top