2016-03-31 10 views
0

Ich versuche, die Erstellung einer benutzerdefinierten Konfigurationsabschnitt zum ersten Mal zu implementieren und bin ziemlich fertig.C# Stuck Erstellen von benutzerdefinierten Konfiguration Abschnitt

Als Beispiel nehme ich einen benutzerdefinierten Abschnitt zum Speichern einer Liste von CSV-Dateien erstellen wollte durch mein Programm zu lesen in - Jede Datei daher mit:

  • Ein Pfad zur Datei
  • A Delimiter
  • Eine Liste der CsvColumn (eine andere Art)

Dann wird jede CsvColumn Eigenschaften haben könnten wie:

012.351.
  • Der Name in der Datei über Config oder nicht getan werden
  • Es Typ ist

(Bitte ignorieren Sie, ob das gut ist, das ist nur ein Beispiel ist eine Hierarchie zu geben, so kann ich lernen, wie man um dies zu tun).

Also habe ich die folgende Konfigurationsdatei erstellt:

<configSections> 
    <section name="CsvData" type="CSV_Loader.CsvData, CSV_Loader" /> 
</configSections> 

<CsvData> 
    <CsvFiles> 
     <CsvFile Path="MyPath1" Delimiter=","> 
      <CsvColumn NameInFile="Col1" Type="System.String"/> 
      <CsvColumn NameInFile="Col2" Type="System.String"/> 
      <CsvColumn NameInFile="Col3" Type="System.Double"/> 
     </CsvFile> 
     <CsvFile Path="MyPath2" Delimiter=","> 
      <CsvColumn NameInFile="Col1" Type="System.String"/> 
     </CsvFile> 
    </CsvFiles> 
</CsvData> 

Und jetzt benutzerdefinierte Klassen erstellen, basierend auf dem Beispiel/Lösung gegeben here und bin immer schrecklich stecken ich suche. Mein aktueller Code sieht in etwa wie folgt:

CsvColumn:

public class CsvColumn : ConfigurationElement 
{ 
    [ConfigurationProperty("NameInFile", IsRequired = true, IsKey = true)] 
    public string NameInFile 
    { 
     get { return (string)this["NameInFile"]; } 
    } 

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

(FYI - Ich mag meine Type als ein tatsächlichen Type Variable speichern, aber ich stelle es als String nur für den Fall, dass wurde, wo mein Problem war)

csvfile:

[ConfigurationCollection(typeof(CsvColumn), AddItemName = "CsvColumn", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class CsvFile : ConfigurationElementCollection 
{ 
    [ConfigurationProperty("Path", DefaultValue = "", IsKey = true, IsRequired = true)] 
    public string Path 
    { 
     get { return (string)(base["Path"]); } 
    } 

    [ConfigurationProperty("Delimiter", DefaultValue = ",", IsRequired = true)] 
    public string Delimiter 
    { 
     get { return (string)(base["Delimiter"]); } 
    } 

    public CsvColumn this[int index] 
    { 
     get { return (CsvColumn)BaseGet(index); } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

    public void Add(CsvColumn column) 
    { 
     BaseAdd(column); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new CsvColumn(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((CsvColumn)element).NameInFile; 
    } 

    public void Remove(CsvColumn column) 
    { 
     BaseRemove(column.NameInFile); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(String name) 
    { 
     BaseRemove(name); 
    } 
} 

csvfile Collection:

[ConfigurationCollection(typeof(CsvFile), AddItemName = "CsvFile", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class CsvFiles : ConfigurationElementCollection 
{ 
    public CsvFile this[int index] 
    { 
     get { return (CsvFile)BaseGet(index); } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

    public void Add(CsvFile file) 
    { 
     BaseAdd(file); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new CsvFile(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((CsvFile)element).Path; 
    } 

    public void Remove(CsvFile file) 
    { 
     BaseRemove(file.Path); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(String name) 
    { 
     BaseRemove(name); 
    } 
} 

CSVData:

public class CsvData : ConfigurationSection 
{ 
    [ConfigurationProperty("CsvFiles")] 
    public CsvFiles CsvFiles 
    { 
     get { return base["CsvFiles"] as CsvFiles; } 
    } 
} 

Und ich versuche es in meinem Code zu nennen wie folgt:

var csvData = (ConfigurationManager.GetSection("CsvData") as CsvData); 

Aber ich bin immer ein ConfigurationExceptionUnrecognized element 'CsvColumn'. Und ich kann nicht herausfinden, warum.

Meine Hauptfragen sind:

  1. Was mache ich falsch?
  2. Gibt es einen einfacheren (Generic) Weg, dies zu implementieren, der diesen Prozess einfacher machen würde?

Vielen Dank !!!

+1

Bitte geben Sie die vollständigen Details der Ausnahme und nicht nur der Name der Ausnahme –

+0

@ChrisDunaway, Sorry, ich hatte es in, aber dann vergessen, es zu veröffentlichen .... Ich werde es jetzt hinzufügen .... –

Antwort

2

Ich bin nicht sicher, warum dies geschieht, vermutlich einen Fehler im Rahmen, aber wenn man diese verschachtelt ConfigurationElementCollection Instanzen haben scheint es die AddItemName auf dem ConfigurationCollection Attribut der inneren Sammlung zu ignorieren. Sie können dies selbst bestätigen, indem Sie Ihre CsvColumn Elemente zu add Elementen ändern, und es wird ordnungsgemäß deserialisiert.

Hinzufügen von den folgenden Konstruktor auf Ihre CsvFile Klasse sollte Ihr Problem lösen:

public CsvFile() 
    { 
     AddElementName = "CsvColumn"; 
    } 

Für Ihre zweite Frage haben Sie die Bibliothek versucht CsvHelper

+0

IT FREAKING WORKED !!!!!! - ** DANKE !!!! ** - Wirklich, ich kann dir nicht genug danken !! - Das hat mich NUTS gehen !!! –

+0

Was die zweite Frage betrifft - ich frage mich eine generische Lösung für den Umgang mit Config-Dateien, nicht CSV-Dateien ... irgendwelche Ideen da ?? –

+0

Gern geschehen. Ich bin mir nicht sicher, ob ich benutzerdefinierte Konfigurationsabschnitte generisch behandeln soll. Heutzutage tendiere ich dazu, sie für meine eigene Konfiguration zu meiden und stattdessen als JSON zu speichern. –

Verwandte Themen