2010-10-13 10 views
10

Ich möchte eine benutzerdefinierte Konfigurationsdatei für meine App und JSON scheint ein geeignetes Format *.Erste Schritte mit JSON in .net und mono

Ich weiß, dass es JSON-Bibliotheken für .NET gibt, aber ich konnte keine gute vergleichende Überprüfung von ihnen finden. Außerdem muss meine App auf Mono laufen, so dass es noch schwieriger ist herauszufinden, welche Bibliothek verwendet werden soll.

Hier ist, was ich gefunden habe:

ich das Lesen nicht vergessen, dass es eine eingebaute Möglichkeit, zu (de) serialisieren JSON als auch, aber ich erinnere mich nicht, was es ist.

Welche Bibliothek wäre am einfachsten in Mono auf Linux zu verwenden? Geschwindigkeit ist nicht kritisch, da die Daten klein sind.

* Da die App auf einer kopflosen Linux-Box ausgeführt wird, muss ich die Befehlszeile verwenden und möchte weiter auf ein Minimum tippen, so dass ich XML ausgeschlossen. Außerdem konnte ich keine Bibliothek finden, um mit INF-Dateien zu arbeiten, ich bin nicht vertraut mit Standard-Linux-Konfigurationsdatei-Formaten und JSON ist mächtig.

Antwort

4

Die DataContractJsonSerializer kann JSON serialization behandeln, aber es ist nicht so leistungsfähig wie einige der Bibliotheken zum Beispiel hat es keine Parse-Methode.

Dies könnte ein Weg sein, es ohne Bibliotheken zu tun, wie ich glaube, Mono hat diese Klasse implementiert.

Um besser lesbar JSON Markup Ihre Klasse mit Attributen zu erhalten:

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

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

In meinen Tests hat Mono 2.8 diese Klasse tatsächlich implementiert. – Pat

+0

Es sieht so aus, als ob DCJS den JSON nicht sehr lesbar formatiert, aber es funktioniert! – Pat

+0

Versuchen Sie, Anmerkungen zu machen, um bessere Elementnamen zu erhalten. Siehe meine Bearbeitung. –

2

Im Folgenden meine Implementierung ist die DataContractJsonSerializer verwenden. Es funktioniert in Mono 2.8 unter Windows und Ubuntu 9.04 (mit Mono 2.8 aus der Quelle). (Und natürlich funktioniert es in .NET!) Ich habe einige Vorschläge von Best Practices: Data Contract Versioning umgesetzt. Die Datei wird im selben Ordner wie die exe gespeichert (nicht sicher, ob ich das am besten gemacht habe, aber es funktioniert in win und 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); 
    } 
}