Getting started with JSON in .net and mono

10,557

Solution 1

The DataContractJsonSerializer can handle JSON serialization but it's not as powerful as some of the libraries for example it has no Parse method.

This might be a way to do it without libraries as I beleive Mono has implemented this class.

To get more readable JSON markup your class with attributes:

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

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

Solution 2

Below is my implementation using the DataContractJsonSerializer. It works in mono 2.8 on windows and ubuntu 9.04 (with mono 2.8 built from source). (And, of course, it works in .NET!) I've implemented some suggestions from Best Practices: Data Contract Versioning . The file is stored in the same folder as the exe (not sure if I did that in the best manner, but it works in win and 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);
    }
}
Share:
10,557
Pat
Author by

Pat

Previously a "Software Engineer" at a small electronics design shop, now a mostly JS and python dev interested in learning, doing, and teaching.

Updated on July 20, 2022

Comments

  • Pat
    Pat almost 2 years

    I would like to keep a custom configuration file for my app and JSON seems like an appropriate format*.

    I know that there are JSON libraries for .NET, but I couldn't find a good comparative review of them. Also, my app needs to run on mono, so it's even harder to find out which library to use.

    Here's what I've found:

    I remember reading that there is a built-in way to (de)serialize JSON as well, but I don't recall what it is.

    What library would be easiest to use in mono on linux? Speed isn't critical, as the data will be small.

    *Since the app runs on a headless linux box, I need to use the command line and would like to keep typing down to a minimum, so I ruled out XML. Also, I couldn't find any library to work with INF files, I'm not familiar with standard linux config file formats, and JSON is powerful.

  • Pat
    Pat over 13 years
    In my tests mono 2.8 has indeed implemented this class.
  • Pat
    Pat over 13 years
    It looks like DCJS doesn't format the JSON in a very user-readable manner, but it works!
  • Pat
    Pat over 13 years
    I wasn't referring to the naming scheme, I was talking about indentation (i.e. it doesn't use white space in the JSON output, which isn't very readable).
  • Rob Stevenson-Leggett
    Rob Stevenson-Leggett over 13 years
    Oh, yes that is a problem. If you want to view it in Firefox though the JSON View extension will format it for you. Otherwise JSON.Net has a ToString method which can do Indented or non-indented.
  • Omri Gazitt
    Omri Gazitt over 12 years
    Is there a way to use DataContractJsonSerializer with MonoTouch? I have MonoDevelop 2.8.5 and it appears to only allow me to use .NET 2.0 reference assemblies when creating a MonoTouch library (which I would like to use from my MonoTouch app). Is there a MonoTouch "binding" for .NET 4.0?