Building a JSON Configuration Section

2019-04-03 09:29发布

问题:

Is there a way to have configuration sections written in JSON instead of XML?

Let's suppose I have the following ConfigurationSection:

public class UsersConfig : ConfigurationSection {

      [ConfigurationProperty("users",
                             IsRequired = false)]
      public UserCollection Users {
           get { return this["users"] as UserCollection; }
      }
}

[ConfigurationCollection(typeof(UserElement),
     AddItemName = "user"]
public class UsersCollection : ConfigurationElementCollection {
      protected override ConfigurationElement CreateNewElement() {
            return new UserElement();
      }

      protected override object GetElementKey(ConfigurationElement element) {
            return ((UserElement)element).Name;
      }
}

public class UserElement : ConfigurationElement {

     [ConfigurationProperty("name",
                            IsRequired = true,
                            IsKey = true)]
     public string Name {
          get { return this["name"] as string; }
          set { this["name"] = value; }
     }
}

I can then create the following XML configuration section:

<users-config>
      <users>
            <user name="Matt458" />
            <user name="JohnLennon" />
      </users>
</users-config>

What I would want to achieve is to mantain the same UsersConfig class, but instead of mapping it to XML, I would like to map it to a JSON:

{
    "users": [
        {
            "name": "Matt458"
        },
        {
             "name": "JohnLennon"
        }
    ]
}

回答1:

this library might help you: https://github.com/Dynalon/JsonConfig :

from the documentation:

JsonConfig is a simple to use configuration library, allowing JSON based config files for your C#/.NET application instead of cumbersome web.config/application.config xml files. It is based on JsonFX and C# 4.0 dynamic feature. Allows putting your programs config file into .json files, where a default config can be embedded as a resource or put in the (web-)application folder. Configuration can be accessed via dynamic types, no custom classes or any other stub code is necessary. JsonConfig brings support for config inheritance, meaning a set of configuration files can be used to have a single, scoped configuration at runtime which is a merged version of all provided configuration files.



回答2:

If I understand correctly you essentially want to define web.config sections as JSON rather than XML.

There is currently nothing out of the box that does this that I am aware of. However one possible solution is to use Gulp to dynamically write your web.config file as part of your build step. I don't have a concrete example as I'm not aware of anyone doing this, but this might give you a pointer.

First have a look at this article that discusses how you can use the xmlpoke module to write XML:

http://www.mikeobrien.net/blog/using-gulp-to-build-and-deploy-dotnet-apps-on-windows/

Reading JSON in Gulp would be a piece of cake, so you just need to map the JSON into XML. You can then add the Gulp task to your build step by editing your .proj xml file (gulp should be installed globally on the machine the build is being performed on).

  1. Open your proj file in a text editor and locate this section:

    <Project>
        <Target Name="BeforeBuild">
        <!-- Insert tasks to run before build here -->
        </Target>
    </Project>
    
  2. Replace the comment with a gulp command

    gulp taskname
    

An alternative is to use a library such as Newtonsoft to read a JSON file from the disk. Then create your own attributes and system for mapping the values to the properties in your class. This is not straight forward but could certainly be done with some effort.



回答3:

I'm recommending to use FX.configuration, you can add it from NuGet. you can find it at: http://nugetmusthaves.com/Package/FX.Configuration

some code examples can be found at: https://bitbucket.org/friendlyx/fx.configuration

it enables you to add to the App.config stuff like: < add key="JsonConfig" value="{ 'Id': '42', 'Name': 'foo' }" />

another option when using the FX.configuration is to add a new config.json file with all your configuration and at the creation of the instance it will read and parse it.

the following code does exactly what you need with the new json config file.

using System.Collections.Generic;
using FX.Configuration;
namespace JsonConfigurationConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            var config = new Users();
        }
    }
    public class Users : JsonConfiguration
    {
        public List<User> users { get; set; }
    }
    public class User
    {
        public string name { get; set; }
    }
}


回答4:

You can change your own UsersConfig class that it will be able to serialize and deserialize to JSON. Then write another class that will retrieve configuration from your file. In app.config you can add single setting that will point you to the place where you store your json config.

You can achieve this easily by using Json.Net and adding attributes to your UsersConfig class.



回答5:

// To convert an XML node contained in string xml into a JSON string

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);

// To convert JSON text contained in string json into an XML node

XmlDocument doc = JsonConvert.DeserializeXmlNode(json);

Documentation here: Converting between JSON and XML with Json.NET