4

I have a .config file with ini format called menu.config. I created a C# Web form Application in Visual Studio 2010, and I want to access/modify the values of this file. For example, edit Enable=1 to Enable=2 on [Menu 1]. I have no idea how to start it. Hope someone can give me some suggestions, thank you!

[Menu1]
Enabled=1
Description=Fax Menu 1

[Menu2]
Enabled=1
description=Forms
Alison
  • 105
  • 2
  • 9
  • What is your App type exactly? Are you want to store these configurations inside web.config? am i right? – Ali Adlavaran Jun 24 '15 at 04:15
  • 3
    possible duplicate of [Reading/writing an INI file](http://stackoverflow.com/questions/217902/reading-writing-an-ini-file) – Brendan Green Jun 24 '15 at 04:28
  • @BrendanGreen that case is apply to specific `.ini` file, however I want to read `.config` file which is **XML Configuration File** with `ini` format. – Alison Jun 24 '15 at 09:22
  • @AliAdl my app type is **C# Web Form Application**. I don't want to store those configurations inside `web.config`, because it already is a **XML configuration file**. I just want to access/modify those values. – Alison Jun 24 '15 at 09:32
  • @Alison The sample of your file above is most certainly not XML. Perhaps you can clarify with updates to your question? Also, based on some of you other comments - the extension of the file doesn't matter (`ini` vs `config`) if the **content of the file is the same**. The duplicate I linked to still applies. – Brendan Green Jun 24 '15 at 22:22
  • @BrendanGreen I was confused about extension, thank you for your answer! One thing is I did is use `StreamReader` to read file, because it can read any file. But I don't know how to modify values. I'm still looking for any simple answer. Right now I think @Shan 's answer is closer to what I did. – Alison Jun 25 '15 at 02:42

3 Answers3

4

I suggest you to store values in Web.config file and retrieve them in all application. U need to store them in app settings

<appSettings>
  <add key="customsetting1" value="Some text here"/>
</appSettings>

and retrieve them as :

string userName = WebConfigurationManager.AppSettings["customsetting1"]

If you want to read from specific file.

Use Server.Mappath for setting path. Following will be the code.

using System;
using System.IO;

class Test
{
    public void Read()
    {
        try
        {
            using (StreamReader sr = new StreamReader("yourFile"))
            {
                String line = sr.ReadToEnd();
                Console.WriteLine(line);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }
    }
}
Shan Khan
  • 9,667
  • 17
  • 61
  • 111
  • 1
    The draw back here is in the example they have multiple attributes for each menu item versus the simple key value pair. If the OP wanted to use the web.config they may want to look at creating some custom config sections to accommodate. https://msdn.microsoft.com/en-us/library/2tw134k3(v=vs.140).aspx. Otherwise just serve the ini up from the file system and write back to it. – inspiredcoder Jun 24 '15 at 04:28
  • One problem is I have many existing `.config files` that have same format as `menu.config`. So I don't want to store all the value to **Web.config** Is there any sample way to do it? @Shan – Alison Jun 24 '15 at 07:59
1

This Code Project gives a very straight forward example of how to read an ini file. However as already stated in other examples you really should use the .net app.config system.

http://www.codeproject.com/Articles/1966/An-INI-file-handling-class-using-C

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Ini
{
    /// <summary>
    /// Create a New INI file to store or load data
    /// </summary>
    public class IniFile
    {
        public string path;

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section,
            string key,string val,string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section,
                 string key,string def, StringBuilder retVal,
            int size,string filePath);

        /// <summary>
        /// INIFile Constructor.
        /// </summary>
        /// <PARAM name="INIPath"></PARAM>
        public IniFile(string INIPath)
        {
            path = INIPath;
        }
        /// <summary>
        /// Write Data to the INI File
        /// </summary>
        /// <PARAM name="Section"></PARAM>
        /// Section name
        /// <PARAM name="Key"></PARAM>
        /// Key Name
        /// <PARAM name="Value"></PARAM>
        /// Value Name
        public void IniWriteValue(string Section,string Key,string Value)
        {
            WritePrivateProfileString(Section,Key,Value,this.path);
        }

        /// <summary>
        /// Read Data Value From the Ini File
        /// </summary>
        /// <PARAM name="Section"></PARAM>
        /// <PARAM name="Key"></PARAM>
        /// <PARAM name="Path"></PARAM>
        /// <returns></returns>
        public string IniReadValue(string Section,string Key)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(Section,Key,"",temp, 
                                            255, this.path);
            return temp.ToString();

        }
    }
}
CathalMF
  • 9,705
  • 6
  • 70
  • 106
  • Again, this case is only apply to `.ini` file, but my file extension for **menu** is `.config`. – Alison Jun 24 '15 at 09:27
  • @Alison .ini or .config is just a file name. It doesnt matter. What matters is how the file is formatted and you are formatting your file in an INI format. – CathalMF Jun 24 '15 at 12:14
0

In order to implement collection configuration. You can use ConfigurationSection and ConfigurationElementCollection in your web.config.

One advantage of using ConfigurationSection is that you can separate physical files of Menu configuration and rest of web.config configuration. That is very handful when publishing the app on host environments. (see this)

First you need to create Menu config class

public class MenuConfig : ConfigurationElement
  {
    public MenuConfig () {}

    public MenuConfig (bool enabled, string description)
    {
      Enabled = enabled;
      Description = description;
    }

    [ConfigurationProperty("Enabled", DefaultValue = false, IsRequired = true, IsKey = 

true)]
    public bool Enabled
    {
      get { return (bool) this["Enabled"]; }
      set { this["Enabled"] = value; }
    }

    [ConfigurationProperty("Description", DefaultValue = "no desc", IsRequired = true, 

IsKey = false)]
    public string Description
    {
      get { return (string) this["Description"]; }
      set { this["Description"] = value; }
    }
  }

Second define ConfigurationElementCollection if menu collection

public class MenuCollection : ConfigurationElementCollection
  {
    public MenuCollection()
    {
      Console.WriteLineMenuCollection Constructor");
    }

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

    public void Add(MenuConfig menuConfig)
    {
      BaseAdd(menuConfig);
    }

    public void Clear()
    {
      BaseClear();
    }

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

    protected override object GetElementKey(ConfigurationElement element)
    {
      return ((MenuConfig) element).Port;
    }

    public void Remove(MenuConfig menuConfig)
    {
      BaseRemove(menuConfig.Port);
    }

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

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

Third create high level ConfigurationSection that is entry point of your custom configuration

public class MenusConfigurationSection : ConfigurationSection
{
   [ConfigurationProperty("Menus", IsDefaultCollection = false)]
   [ConfigurationCollection(typeof(MenuCollection),
       AddItemName = "add",
       ClearItemsName = "clear",
       RemoveItemName = "remove")]
   public MenuCollection Menus
   {
      get
      {
         return (MenuCollection)base["Menus"];
      }
   }
}

Use the section in web.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <configSections>
      <section name="MenusSection" type="{namespace}.MenusConfigurationSection, {assembly}"/>
   </configSections>
   <MenusSection>
      <Menus>
         <add Enabled="true" Description="Desc 1" />
         <add Enabled="true" Description="Desc 1" />
      </Menus>
   </ServicesSection>
</configuration>
Community
  • 1
  • 1
farid bekran
  • 2,684
  • 2
  • 16
  • 29
  • Is that mean I still need to store those value in **Web.config**? `menu.config` uses `ini` format, so I'm not sure how to read(access) it. – Alison Jun 24 '15 at 07:27
  • If you want to save exactly ini format you can use solutions mentioned in [this question](http://stackoverflow.com/questions/217902/reading-writing-an-ini-file) – farid bekran Jun 24 '15 at 07:38
  • this answer is xml equivalent of your ini file – farid bekran Jun 24 '15 at 07:55
  • Another question: there are Errors for `Port = port; ReportType = reportType;`. It said undefined variables. Where I should define them? There are some typos in your code. Maybe you can edit it? – Alison Jun 24 '15 at 07:57