Начало работы с 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);
}
}