【问题标题】:Deserializing array of enum values wih JSON.NET使用 JSON.NET 反序列化枚举值数组
【发布时间】:2012-05-22 19:02:02
【问题描述】:

我正在尝试使用 JSON.NET 反序列化来自第三方 Web 服务的响应。这是我的(人为的)示例的完整代码,显示了我正在尝试做的事情:

namespace JsonNetTests
{
public enum Parameter
{
    Alpha = 1,
    Bravo = 2,
    Charlie = 3,
    Delta = 4
}

public class ResponseElement
{
    public int Id { get; set; }

    public string Name { get; set; }

    [JsonProperty(ItemConverterType = typeof(StringEnumConverter))]
    public Parameter[] Parameters { get; set; }
}

public class ResponseBody
{
    public string Locale { get; set; }
    public string[] Errors { get; set; }
    public ResponseElement[] ResponseElements { get; set; }
}

[TestFixture]
public class JsonNetTest
{
    [Test]
    public void TestEnumArray()
    {
        string jsonResponse = @"
{""ResponseBody"": {
""Locale"": ""en-US"",
""Errors"": [],
""ResponseElements"": [{
    ""Id"": 1,
    ""Name"": ""ABC"",
    ""Parameters"" : {
        ""Parameter"" : ""Alpha""
    },
    }, {
    ""Id"": 2,
    ""Name"": ""BCD"",
    ""Parameters"" : {
        ""Parameter"" : ""Bravo""
    },
    }
]
}}
";

        JObject rootObject = JObject.Parse(jsonResponse);
        JToken rootToken = rootObject.SelectToken("ResponseBody");

        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.MissingMemberHandling = MissingMemberHandling.Error;

        ResponseBody body = JsonConvert.DeserializeObject<ResponseBody>(rootToken.ToString(), settings);

        foreach (var element in body.ResponseElements)
        {
            Console.WriteLine(string.Format("{0}: {1}", element.Id, element.Name));
            foreach (var parameter in element.Parameters)
            {
                Console.WriteLine(string.Format("\t{0}", parameter));
            }
        }
    }
}
}

我得到以下异常:

Newtonsoft.Json.JsonSerializationException:无法将 JSON 对象(即 {"name":"value"})反序列化为类型“JsonNetTests.Parameter[]”。 反序列化的类型应该是普通的 .NET 类型(即不是像整数这样的原始类型,不是像数组或列表这样的集合类型)或字典类型(即字典)。 要强制 JSON 对象反序列化,请将 JsonObjectAttribute 添加到类型。路径“ResponseElements[0].Parameters.Parameter”,第 9 行,位置 21。

我尝试使用 ItemConverterType 属性来指定如何反序列化数组:

[JsonProperty(ItemConverterType = typeof(StringEnumConverter))]

但这也无济于事。有人可以建议吗?

【问题讨论】:

    标签: c# .net json.net deserialization


    【解决方案1】:

    您正试图将一个对象填充到一个数组中。 ResponseElement.Parameters 是一个枚举数组,您的 json 代码使用一个对象来描述每个参数。

    你的 json 看起来像这样:

    // some json
    "Parameters" : {
        "Parameter" : "Alpha"
    },
    // more json
    

    但要将其转换为枚举数组,它应该如下所示:

    // some json
    "Parameters" : [ "Alpha", "Bravo" ],
    // more json
    

    如果你不能改变json,你可以改变你的模型:

    public enum ParameterEnum 
    {
        Alpha = 1,
        Bravo = 2
    }
    
    public ParameterContainer
    {
        [JsonProperty(ItemConverterType = typeof(StringEnumConverter))]
        public ParameterEnum Parameter {get;set;}
    }
    
    public class ResponseElement
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public ParameterContainer[] Parameters { get; set; }
    }
    

    实际上,您将 json 序列化为一个 ParameterContainers 数组,这将公开它们的值。

    【讨论】:

    • 感谢您的回复!我试图反序列化的类型不是我制造的。它是根据第三方的 Web 服务的 WSDL 自动生成的。他们提供了他们 API 的 SOAP 和 JSON 版本,我想重用 SOAP 的 Reference.cs 中的类。
    • 我可以编写自己的类来反序列化,但我试图避免它,因为第三方的类是巨大的(根本不像我的简化示例),它们有 30 多个属性,大多数其中复杂的。有没有什么方法可以在不改变 JSON(不可能)或代理类的情况下实现反序列化,只使用属性(或者可能是自定义转换器)?
    • 哇。让我考虑一下,我会回复你的。
    猜你喜欢
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 2014-09-22
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多