Linux .net 和 mono 中的 JSON 入门

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3926079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:39:55  来源:igfitidea点击:

Getting started with JSON in .net and mono

c#.netlinuxjsonmono

提问by Pat

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

我想为我的应用程序保留一个自定义配置文件,而 JSON 似乎是一种合适的格式*。

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.

我知道有适用于 .NET 的 JSON 库,但我找不到对它们的很好的比较评论。此外,我的应用程序需要在单声道上运行,因此更难找出要使用的库。

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.

我记得读到有一种内置的方式来(反)序列化 JSON,但我不记得它是什么。

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

在 linux 上的单声道中最容易使用什么库?速度并不重要,因为数据会很小。

*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.

*由于该应用程序在无头 linux 机器上运行,因此我需要使用命令行并希望尽可能减少输入内容,因此我排除了 XML。另外,我找不到任何可以处理 INF 文件的库,我不熟悉标准的 linux 配置文件格式,而且 JSON 很强大。

采纳答案by Rob Stevenson-Leggett

The DataContractJsonSerializercan handle JSON serializationbut it's not as powerful as some of the libraries for example it has no Parse method.

DataContractJsonSerializer可以处理JSON序列化,但它不是那样强大一些,例如它没有解析方法库。

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

这可能是一种没有库的方法,因为我相信 Mono 已经实现了这个类。

To get more readable JSON markup your class with attributes:

要使用属性获得更具可读性的 JSON 标记您的类:

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

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

回答by Pat

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).

下面是我使用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);
    }
}