2013-12-21 4 views
2

Я рассмотрел связанный с этим вопрос Intellisense for custom config section problem with namespaces, который описывает ту же проблему, что и у меня. Хотя решение для меня не работает.Добавление Intellisense в пользовательской конфигурации

Я вставляю все свое решение здесь, поэтому другие также могут видеть, как достигается желаемая функция. Я следил за множеством руководств по настраиваемым разделам конфигурации и тем, как достичь Intellisense в файлах конфигурации, но никто не решает проблему, которую я испытываю.

Я получаю ConfigurationErrorException:

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

Я не знаю, жарко, чтобы это исправить.

Мой пользовательский раздел конфигурации класса:

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

Мои Перечисления:

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

Мои 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> 

Мой файл схемы:

<?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> 

... и наконец мой 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(); 
     } 
    } 
} 

Теперь у меня есть IntelliSense в моей конфигурации рабочих все в порядок. Но я получаю исключение при попытке сопоставить свои настройки при запуске моей программы. Я могу удалить часть «xmlns =» http://tempuri.org/MyConfiguration.xsd «в моем « <MyConfiguration xmlns="http://tempuri.org/MyConfiguration.xsd"> »в моем файле App.config и добавить местоположение в его физическое местоположение в свойствах моего App.config в «Схемах» и intellisense также работает и отображает. Но тогда физическое местоположение привязано к моей машине, и я хочу, чтобы местоположение было относительным, поскольку файл схемы является частью моего решения VS. Я предпочитаю ссылаться на файл в моем решении.

Что мне не хватает? Я подозреваю, что мне нужно украсить файл класса MyConfiguration пространством имен и схемами?

+1

-1: как вы просили через комментарии, я рассмотрел ваш вопрос. Возможно, теперь другие будут делать то же самое. –

+0

Я не спрашивал через комментарии. Я добавил этот вопрос вчера и начал поиск по предыдущим задаваемым вопросам по тому же вопросу в stackoverflow. Я просто попросил посмотреть здесь свою проблему. Я действительно не понимаю, почему голосование падает, а не пытается мне помочь. Я все еще ищу исправление. Поэтому вместо того, чтобы проголосовать за мою нить, попробуйте помочь мне ... – codingjoe

+0

Может кто-то уточнить, почему у вас есть пропуски? Я действительно пытался исправить эту проблему и решил сделать полную нить с подробным объяснением и кодом, чтобы другие могли получить помощь в будущем. – codingjoe

ответ

2

Я нашел проблему в вашем коде, и это заканчивается довольно простым. Вам нужно добавить тег Xmlns к классу MyConfiguration так:

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

Тогда ConfigurationManager умеет читать это.

+0

Будет работать, но выглядит скорее как хак, а не исправление проблема с пространством имен. – codingjoe

+0

Ну. Это не так. Все это имеет смысл, позвольте мне объяснить. Интеграция XML/XSD/Intellisense знает, как читать XML, включая «сохраненное» ключевое слово xmlns. С другой стороны, класс ConfigurationManager не является умным. Он просто считывает каждый атрибут и элемент в XML-фрагменте, включая ключевое слово xmlns, что означает, что он будет жаловаться, если не найдет свойство в своем классе, который отображает его. –

+0

Глядя на количество времени, которое я потратил, пытаясь исправить это, и попробуйте разные подходы при десериализации настроек конфигурации. Я собираюсь принять этот ответ. Я на самом деле также нашел этот подход решения где-то, когда я googled пару дней назад. – codingjoe

Смежные вопросы