Home > Software design >  C# read XML config file through deserialize
C# read XML config file through deserialize

Time:12-26

I'm trying to create a very simple class, object of which reads specified XML-file during variable init stage and makes values from said XML available as read-only properties.

So I need to feed it path as string to following structure:

<?xml version="1.0" encoding="utf-8"?>
<PLEXUpdateConfig>
    <Release>1</Release>
    <InstallPath>%ProgramW6432%</InstallPath>
    <CheckEveryXMinutes>20</CheckEveryXMinutes>
</PLEXUpdateConfig>

...and refer to it later like:

Console.WriteLine("Release {0}, path {1}, interval {2} minutes", vConfigFile.Release, vConfigFile.InstallPath, vConfigFile.CheckEveryXMinutes);

Right now I have this class:

public class PLEXUpdateConfig
{
    public uint Release { get; }
    public string InstallPath { get; }
    public uint CheckEveryXMinutes { get; }


    public class XMLStructure
    {
        public String Release { get; set; }
        public String InstallPath { get; set; }
        public String CheckEveryXMinutes { get; set; }

        public override string ToString()
        {
            return $"(Release: {Release}, InstallPath: {InstallPath}, CheckEveryXMinutes {CheckEveryXMinutes})";
        }
    }

    public PLEXUpdateConfig(string filePath)
    {
        XMLStructure vConfig;

        using (var reader = new StreamReader(filePath))
        {
            vConfig = (XMLStructure)new XmlSerializer(typeof(XMLStructure)).Deserialize(reader);
        }

        Release = (uint)int.Parse(vConfig.Release);
        InstallPath = vConfig.InstallPath;
        CheckEveryXMinutes = (uint)int.Parse(vConfig.CheckEveryXMinutes);

    }
}

...which I'm trying to call from Main like this:

var vConfigFile = new PLEXUpdateConfig(vProgram.gReleaseFilePath);

And it won't work, complaining about protection level:

Unhandled Exception: System.InvalidOperationException: plex_update_cmd.Program is inaccessible due to its protection level. Only public types can be processed.
   at System.Xml.Serialization.TypeDesc.CheckSupported()
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference)
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference)
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.ModelScope.GetTypeModel(Type type, Boolean directReference)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at plex_update_cmd.Program.PLEXUpdateConfig..ctor(String filePath) in ..\plex-update.cs:line 46
   at plex_update_cmd.Program.Main(String[] args) in ..\plex-update.cs:line 64

But both PLEXUpdateConfig class and nested XMLStructure class are as public, as they could be, so I don't really understand where is the issue. Could you please help me?

CodePudding user response:

Why declare an inner class for configuration ? It is normal in this case to have a scoop exeption. In addition, the inner class has the same variable name.

Please try this

public class PLEXUpdateConfig
{
    public uint Release { get; }
    public string InstallPath { get; }
    public uint CheckEveryXMinutes { get; }


    public PLEXUpdateConfig(string filePath)
    {
        XMLStructure vConfig;

        using (var reader = new StreamReader(filePath))
        {
            vConfig = (XMLStructure)new XmlSerializer(typeof(XMLStructure)).Deserialize(reader);
        }

        Release = (uint)int.Parse(vConfig.Release);
        InstallPath = vConfig.InstallPath;
        CheckEveryXMinutes = (uint)int.Parse(vConfig.CheckEveryXMinutes);
    }
}

    public class XMLStructure
    {
        public String Release { get; set; }
        public String InstallPath { get; set; }
        public String CheckEveryXMinutes { get; set; }

        public override string ToString()
        {
            return $"(Release: {Release}, InstallPath: {InstallPath}, CheckEveryXMinutes {CheckEveryXMinutes})";
        }
   }

CodePudding user response:

Turns out it has nothing to do with XMLStructure being nested into PLEXUpdateConfig. It's the PLEXUpdateConfig being nested into Program class. Apparently it's not allowed as well. When I moved PLEXUpdateConfig outside of Program class it went OK

  • Related