2010-10-13 21 views
10

Me gustaría mantener un archivo de configuración personalizado para mi aplicación y JSON parece un formato apropiado *.Comenzando con JSON en .net y mono

Sé que hay bibliotecas JSON para .NET, pero no pude encontrar una buena revisión comparativa de ellas. Además, mi aplicación debe ejecutarse en mono, por lo que es aún más difícil averiguar qué biblioteca usar.

Esto es lo que he encontrado:

Recuerdo haber leído que hay una manera integrada para JSON (de) serializar así, pero yo no recuerdo de qué se trata

¿Qué biblioteca sería más fácil de usar en mono en Linux? La velocidad no es crítica, ya que los datos serán pequeños.

* Dado que la aplicación se ejecuta en un linux sin cabeza, necesito usar la línea de comandos y me gustaría seguir escribiendo al mínimo, por lo que descarté XML. Además, no pude encontrar ninguna biblioteca para trabajar con archivos INF, no estoy familiarizado con los formatos de archivo de configuración de Linux estándar, y JSON es poderoso.

Respuesta

4

El DataContractJsonSerializer puede manejar JSON serialization pero no es tan potente como algunas de las bibliotecas, por ejemplo, no tiene el método Parse.

Esta podría ser una forma de hacerlo sin bibliotecas ya que creo que Mono ha implementado esta clase.

Para obtener más legible JSON markup su clase con atributos:

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

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

En mis pruebas, el mono 2.8 efectivamente ha implementado esta clase. – Pat

+0

Parece que DCJS no formatea el JSON de una manera legible por el usuario, ¡pero funciona! – Pat

+0

Intente hacer anotaciones para obtener mejores nombres de elementos. Ver mi edición –

2

continuación es mi aplicación utilizando el DataContractJsonSerializer. Funciona en mono 2.8 en windows y ubuntu 9.04 (con mono 2.8 construido desde la fuente). (Y, por supuesto, funciona en .NET!) He implementado algunas sugerencias en Best Practices: Data Contract Versioning . El archivo se almacena en la misma carpeta que el exe (no estoy seguro de haberlo hecho de la mejor manera, pero funciona en win y 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); 
    } 
}