json - 使用 json 键存储值,这是一个好方法吗?

标签 json

我正在编写一个rest api,我对json序列化很陌生。

我知道一个 json 对象由成对的 <key>:<value> 组成.

我有一个对象“channels”,它包含多个 channel 对象,这些对象包含一个 id 和一些其他属性,如“x”、“y”和“z”。

在我们的团队中,我们发现了两种表示对象“ channel ”的方式,我看到人们实现的通常方式是这样的:

{
"channels":
    [
        {
            "id":0,
            "x":0,
            "y":0,
            "z":0
        },
        ...
    ]
}

还有这个版本,它使用 id 作为键:
{
"channels":
    {
        "0":
        {
            "x":0,
            "y":0,
            "z":0
        },
        ...
    }
}

请注意,第一个实现显式使用数组,而第二个实现依赖于 <key>直接访问特定 channel 。

表示这个对象的最佳方式是什么?可以将键表示为值(如前一种情况的 id)吗?

现在只有两个 channel (总是 id 0 和 1),但将来我们可能会添加更多。

最佳答案

您应该更喜欢第一种方法,因为以这种方式使用 JSON 更容易、更直观。如果有人想使用您的 API,他们可能会创建模型类来反序列化。使用第一种方法,这很容易:

public class RootObject
{
    public List<Channel> channels { get; set; }
}

public class Channel
{
    public int id { get; set; }
    public int x { get; set; }
    public int y { get; set; }
    public int z { get; set; }
}
事实上,你可以直接获取 JSON 并将其转储到生成器工具中,例如 http://json2csharp.com/获得这些类(class)(这就是我在这里所做的)。
相比之下,使用第二种方法,JSON 中表示 ID 的键是动态的,生成器不会识别这样的动态。所以你会得到这样的东西,需要手动更正:
public class RootObject
{
    public Channels channels { get; set; }
}

public class Channels
{
    public __invalid_type__0 __invalid_name__0 { get; set; }
}

public class __invalid_type__0
{
    public int x { get; set; }
    public int y { get; set; }
    public int z { get; set; }
}
我见过一些人尝试像这样修复它,这将适用于您的单 channel 示例,但显然不会扩展:
public class RootObject
{
    public Channels channels { get; set; }
}

public class Channels
{
    [JsonProperty("0")]
    public Data Item0 { get; set; }
}

public class Data
{
    public int x { get; set; }
    public int y { get; set; }
    public int z { get; set; }
}
要使用动态键正确使用 JSON,类实际上需要如下所示:
public class RootObject
{
    public Dictionary<string, Channel> channels { get; set; }
}

public class Channel
{
    public int x { get; set; }
    public int y { get; set; }
    public int z { get; set; }
}
然而,您需要在此处使用字典这一事实对于临时用户而言并不总是直观的。事实上,我已经忘记了“我如何处理 JSON 中的动态键?”这个问题的次数。是 asked在 StackOverflow 上。帮您的用户一个忙,不要让他们考虑。
除了反序列化 JSON 之外,第一个模型也更好,因为 Channel对象包含有关 channel 的所有数据:id位于对象本身内部。以这种方式传递和使用很容易。转换 List<Channel> 也很简单成Dictionary<int, Channel>稍后如果您需要进行 key 查找:
var dict = rootObject.channels.ToDictionary(ch => ch.id);
使用第二种方法,id与 channel 数据的其余部分分开,因此如果您想将 channel 传递给需要两者的方法,则必须传递两个参数或创建一个新的模型类来将所有内容包装在一起。换句话说,使用起来更别扭。
最重要的是,我认为使用第二种方法根本没有真正的好处。跟着第一个走。

关于json - 使用 json 键存储值,这是一个好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53655587/

相关文章:

c# - 如何控制 JSON 输出中属性的顺序?

java - 如何正确地将数据添加到嵌套 HashMap

javascript - 如何通过 File API 执行 json 文件中的数据?

c# - 带有 Newtonsoft 的 ASP.NET MVC 将对象从 Controller 传递到 View

c# - 使用 Flurl 从 JSON 解析为对象

当值包含单引号 (') 时,PHP json_decode 失败

java - 在 JAVA 中将 JSON 对象作为 POST 发送到 REST 服务

javascript - 将包含 HTML 实体的 JSON 序列化字符串转换为对象

java - 使用 Java 将 JSON 转换为 CSV

c# - 从 C# 枚举到函数/对象名称的 Json 序列化