2010-10-13 65 views
10

我想爲我的應用保留一個自定義配置文件,並且JSON看起來像是合適的格式*。在.net和mono中使用JSON入門

我知道有.NET的JSON庫,但我無法找到一個很好的比較審查。另外,我的應用程序需要在單聲道上運行,因此更難找出要使用哪個庫。

這裏是我發現:

看完記得有一個內置的方式(反)序列化JSON爲好,但我不記得它是什麼。

什麼庫最容易在單聲道Linux上使用?速度並不重要,因爲數據會很小。由於該應用程序運行在無頭Linux機器上,因此我需要使用命令行,並且希望保持最低限度的輸入,所以我排除了XML。另外,我找不到任何庫來處理INF文件,我不熟悉標準的Linux配置文件格式,而且JSON功能強大。

回答

4

DataContractJsonSerializer可以處理JSON serialization,但它不像一些庫那樣強大,例如它沒有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;} 
} 
+0

在我的測試中,mono 2.8確實實現了這個類。 – Pat 2010-10-15 21:14:35

+0

它看起來像DCJS不以用戶可讀的方式格式化JSON,但它的工作原理! – Pat 2010-10-15 21:24:32

+0

嘗試註釋以獲取更好的元素名稱。看我的編輯。 – 2010-10-18 08:38:22

2

以下是使用DataContractJsonSerializer我的實現。它可以在windows和ubuntu 9.04上使用單聲道2.8(使用單聲道2.8來源)。 (當然,它工作在.NET!)我已經從Best Practices: Data Contract Versioning 實施了一些建議。該文件存儲在相同的文件夾作爲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); 
    } 
}