class for this JSON



我正在访问一个返回一些JSON的API,如下所示:

{"stats":{"X":{"Name":"X","Found":"Yes"}},"response":"OK","runtimeMs":798}

我想为它生成 C# 类,我使用了 json2sharp,它生成了诸如根对象的类,我修改如下:

public class RootObject
            {
                public Stats stats { get; set; }
                public string response { get; set; }
                public int runtimeMs { get; set; }
            }
            public class Stats
            {
                public string name { get; set; }
            }
            public class Variant
            {
                public string name { get; set; }
                public string Found { get; set; }
            }

面临的问题是,在类统计中,我使用了名称,因为 json 会回复任何名称,例如 X 或 Y 或 Z。

我能够将 JSON 反序列化为根对象,但无法将任何数据放入统计类中。

JsonConvert.DeserializeObject<RootObject>(response.Content);

知道为什么我可能做错了吗?

您的问题与此类似 如何解析会导致非法 C# 标识符的 JSON 字符串?

因此,您的模型应该是

public class Variant
{
    public string Name { get; set; }
    public string Found { get; set; }
}

public class RootObject
{
    public Dictionary<string, Variant> stats { get; set; }
    public string response { get; set; }
    public int runtimeMs { get; set; }
}

编辑

@evanmcdonnal如果使用 EZI 答案中显示的字典或带有名为 X、Y 和 Z 的字段的对象,则必须到处执行 nullity 或 keyexists 检查才能安全地使用该对象。

我不认为这个简单的linq很难写

rootObj.stats.Values.Where(....); 

rootObj.stats.Keys.Select(....); 
发生这种情况

是因为 json.NET 正在类中查找与 JSON 中的字段名称匹配的属性名称。由于name与 json 中的任何内容都不相似,因此它什么也找不到。

有两种方法可以解决此问题。您可以使用批注来说明要放置的 json 字段是什么,也可以更改属性的名称。但是,从您的帖子中听起来您是在说 json 中可能有一个名为 X 的对象或一个名为 Y 的对象,这两个选项都不会在所有情况下正确反序列化。我将编辑一些关于您可能想要如何处理它的想法。

根据OP的评论,这是您要查找的内容;

        public class RootObject
        {
            public Stats stats { get; set; }
            public string response { get; set; }
            public int runtimeMs { get; set; }
        }
        public class Stats
        {
            public Varient X { get; set; }
            public Varient Y { get; set; }
            public Varient Z { get; set; }
        }
        public class Variant
        {
            public string name { get; set; }
            public string Found { get; set; }
        }

在代码的其他地方,您只需要有两个代码路径或进行转换,以避免到处执行无效性检查。

if (myInstance.X != null)
   // it was X that was in the json
else if (myInstace.Y != null)
   // it was Y
else
   // not sure what happened, perhaps neither X nor Y were present.

现在,另一种选择是使其只是一个中介,然后定义另一个类型,该类型只有一个名为 name 的属性,并为其提供一个构造函数,该构造函数采用RootObject并将任何不为 null 的值分配给它name属性或任何您想要调用它的内容。我自己可能会做这样的事情,因为如果使用 EZI 答案中显示的字典或带有名为 X、Y 和 Z 的字段的对象,您必须到处执行 nullity 或 keyexists 检查才能安全地使用该对象。

相关内容

最新更新