Начало работы с JSON в .net и моно

Я хотел бы сохранить пользовательский файл конфигурации для своего приложения, а JSON выглядит как соответствующий формат *.

Я знаю, что для .NET есть библиотеки JSON, но я не смог найти хороший сравнительный обзор. Кроме того, мое приложение должно работать на моно, поэтому еще сложнее узнать, какую библиотеку использовать.

Вот что я нашел:

Я помню, что читал, что есть встроенный способ (de) сериализации JSON, но я не помню, что это такое.

Какую библиотеку проще всего использовать в моно на linux? Скорость не является критичной, так как данные будут небольшими.

* Поскольку приложение работает в безголовом окне linux, мне нужно использовать командную строку и хотелось бы свести к минимуму, поэтому я исключил XML. Кроме того, я не мог найти какую-либо библиотеку для работы с файлами INF, я не знаком со стандартными форматами файлов конфигурации Linux, а JSON является мощным.

Ответ 1

DataContractJsonSerializer может обрабатывать сериализацию JSON, но это не так сильно, как некоторые из библиотек, например, у него нет метода Parse.

Это может быть способ сделать это без библиотек, поскольку я верю, что Mono реализовала этот класс.

Чтобы получить более читаемый JSON, разметьте свой класс атрибутами:

[DataContract]
public class SomeJsonyThing
{
    [DataMember(Name="my_element")]
    public string MyElement { get; set; }

    [DataMember(Name="my_nested_thing")]
    public object MyNestedThing { get; set;}
}

Ответ 2

Ниже приведена моя реализация с помощью DataContractJsonSerializer. Он работает в моно 2.8 на окнах и ubuntu 9.04 (с моно 2.8, построенным из источника). (И, конечно, он работает в .NET!) Я внедрил некоторые предложения из "Лучшие практики: управление версиями данных" . Файл хранится в той же папке, что и exe (не уверен, что я сделал это наилучшим образом, но он работает в win и linux).

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

using NLog;

[DataContract]
public class UserSettings : IExtensibleDataObject
{
    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }

    [DataMember]
    public int TestIntProp { get; set; }

    private string _testStringField;
}

public static class SettingsManager
{
    private static Logger _logger = LogManager.GetLogger("SettingsManager");

    private static UserSettings _settings;

    private static readonly string _path =
        Path.Combine(
            Path.GetDirectoryName(
                System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName),
            "settings.json");

    public static UserSettings Settings
    {
        get
        {
            return _settings;
        }
    }

    public static void Load()
    {
        if (string.IsNullOrEmpty(_path))
        {
            _logger.Trace("empty or null path");
            _settings = new UserSettings();
        }
        else
        {
            try
            {
                using (var stream = File.OpenRead(_path))
                {
                    _logger.Trace("opened file");
                    _settings = SerializationExtensions.LoadJson<UserSettings>(stream);
                    _logger.Trace("deserialized file ok");
                }
            }
            catch (Exception e)
            {
                _logger.TraceException("exception", e);
                if (e is InvalidCastException
                    || e is FileNotFoundException
                    || e is SerializationException
                    )
                {
                    _settings = new UserSettings();
                }
                else
                {
                    throw;
                }
            }
        }
    }

    public static void Save()
    {
        if (File.Exists(_path))
        {
            string destFileName = _path + ".bak";
            if (File.Exists(destFileName))
            {
                File.Delete(destFileName);
            }
            File.Move(_path, destFileName);
        }
        using (var stream = File.Open(_path, FileMode.Create))
        {
            Settings.WriteJson(stream);
        }
    }
}

public static class SerializationExtensions
{
    public static T LoadJson<T>(Stream stream) where T : class
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        object readObject = serializer.ReadObject(stream);
        return (T)readObject;
    }

    public static void WriteJson<T>(this T value, Stream stream) where T : class
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        serializer.WriteObject(stream, value);
    }
}