2009-01-27 9 views
3

J'essaie d'utiliser les définitions d'entité dans un fichier de configuration pour simplifier les différences entre les versions de développement, d'assurance qualité, d'UAT et de production. Voici un échantillon du début de mon fichier de configuration:Entités DTD dans le fichier de configuration

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE configuration [ 
    <!ENTITY MyStorageLocation "\\MyServer\MyStorageFolder"> 
    <!ENTITY MyDatabaseServer "devdb01"> 
]> 
<configuration> 
    <configSections> 
    <section name="MyCustomSection" type="MyCustomSectionHandler,MyAssembly"/> 
     ... 
    </configSections> 
<connectionStrings> 
    <add name="MyConnectionString" providerName="System.Data.SqlClient" connectionString="Server=&MyDatabaseServer;;Database=MyDatabase;"/> 
</connectionStrings> 
    ... 
<MyCustomSection>&MyStorageLocation;</MyCustomSection> 
</configuration> 

Cela semble fonctionner correctement, et pourquoi pas comme il est XML parfaitement valable, tant que je ne l'utilise l'une de ces entités dans une mesure section de configuration que je finis par appeler ConfigurationManager.GetSection() sur. L'utilisation de l'entité "MyDatabaseServer" dans la chaîne de connexion ne pose aucun problème. Dans l'exemple fourni, tout fonctionnera correctement tant que je n'utilise pas l'entité "MyStorageLocation" dans l'élément MyCustomSection et que je ne rencontre l'erreur que lorsque j'appelle ConfigurationManager.GetSection() pour demander la section personnalisée. Ma meilleure estimation est que la classe ConfigurationManager prend la source brute de l'élément et tente de la charger en tant que XML, en ignorant les entités déclarées pour l'ensemble du fichier .xml. Existe-t-il un meilleur moyen de le faire, à moins de recoder les sections de configuration personnalisées pour prendre en charge les références aux paramètres au lieu de nombreux paramètres absolus?

L'erreur que je reçois est:

2009-01-27 14:00:53,474 [11936] ERROR MyCustomWindowsService [(null)] - Errors starting service -- shutting down 
System.Configuration.ConfigurationErrorsException: Reference to undeclared entity 'MyStorageLocation'. Line 183, position 19. (D:\...\MyCustomWindowsService.exe.config line 183) ---> System.Xml.XmlException: Reference to undeclared entity 'MyStorageLocation'. Line 183, position 19. 
    at System.Xml.XmlTextReaderImpl.Throw(Exception e) 
    at System.Xml.XmlTextReaderImpl.HandleGeneralEntityReference(String name, Boolean isInAttributeValue, Boolean pushFakeEntityIfNullResolver, Int32 entityStartLinePos) 
    at System.Xml.XmlTextReaderImpl.ResolveEntity() 
    at System.Xml.XmlTextReader.ResolveEntity() 
    at System.Xml.XmlLoader.LoadEntityReferenceNode(Boolean direct) 
    at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace) 
    at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc) 
    at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) 
    at System.Xml.XmlDocument.Load(XmlReader reader) 
    at System.Configuration.ErrorInfoXmlDocument.LoadFromConfigXmlReader(ConfigXmlReader reader) 
    at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) 
    at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) 
    at System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) 
    at System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line) 
    --- End of inner exception stack trace --- 
    at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult) 
    at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) 
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) 
    at System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission) 
    at System.Configuration.BaseConfigurationRecord.GetSection(String configKey) 
    at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName) 
    at System.Configuration.ConfigurationManager.GetSection(String sectionName) 
    at MyCustomWindowsService.Monitor() in D:\...\MyCustomWindowsService.cs:line 207 
    at MyCustomWindowsService.Start() in D:\...\MyCustomWindowsService.cs:line 178 

dans les entrailles du ConfigurationManager ...

+0

double possible de [Puis-je déclarer et utiliser des entités DTD dans App.config?] (Http://stackoverflow.com/questions/15132662/can-i-declare-and-use-dtd -entities-in-app-config) –

Répondre

0

Peut-être que votre processeur XML ignore les déclarations ENTITÉ parce qu'ils sont contenus dans une DTD autrement vide! .

Avez-vous une DTD que vous pourriez utiliser pour valider ce document? En l'absence d'une DTD ou d'un schéma, vous ne pouvez pas vraiment dire que le document est valide. Essayez de l'exécuter via un service de validation XML en ligne comme celui de l'URL: http://www.validome.org/xml/validate/

Voici une version modifiée de votre document avec une DTD I fouettée. Voir si cela aide.


<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE configuration [ 
    <!ELEMENT configuration (configSections+, connectionStrings+, MyCustomSection)> 

    <!ELEMENT configSections (section+)> 

    <!ELEMENT section EMPTY> 
    <!ATTLIST section name CDATA #REQUIRED> 
    <!ATTLIST section type CDATA #REQUIRED> 

    <!ELEMENT connectionStrings (add+)> 

    <!ELEMENT add EMPTY> 
    <!ATTLIST add name CDATA #REQUIRED> 
    <!ATTLIST add providerName CDATA #REQUIRED> 
    <!ATTLIST add connectionString CDATA #REQUIRED> 

    <!ELEMENT MyCustomSection (#PCDATA)> 

    <!ENTITY MyStorageLocation "\\MyServer\MyStorageFolder"> 
    <!ENTITY MyDatabaseServer "devdb01"> 
]> 
<configuration> 
    <configSections> 
    <section name="MyCustomSection" type="MyCustomSectionHandler,MyAssembly"/> 
    </configSections> 
    <connectionStrings> 
    <add name="MyConnectionString" providerName="System.Data.SqlClient" connectionString="Server=&MyDatabaseServer;;Database=MyDatabase;"/> 
    </connectionStrings> 
    <MyCustomSection>&MyStorageLocation;</MyCustomSection> 
</configuration> 
Questions connexes