使用Newtonsoft将JSON字符串反序列化为C#对象

3

我一直在处理一个项目,需要调用外部RESTful服务来获取一些数据。

我遇到的问题是,我从服务中获取的响应在不同的情况下是不同的。例如。

在某种情况下,我会收到以下响应

{  
   "id":3000056,
   "posted_date":"2016-04-15T07:16:47+00:00",
   "current_status":"initialized",
   "customer":{  
        "name" : "George",
        "lastName" : "Mike"
   },
   "application_address":{
        "addressLine1" : "Lin1",
        "addressLine2" : "Lin2",
   }

}

在另一种情况下,我得到了以下响应。
 {  
   "id":3000057,
   "posted_date":"2016-04-15T07:16:47+00:00",
   "current_status":"initialized",
   "customer":[],
   "application_address":[]

}

这里的问题是,我有以下模型,并且我正在使用Newtonsoft反序列化对其进行反序列化。
public class Response
    {

        [JsonProperty("id")]
        public int Id { get; set; }

        [JsonProperty("posted_date")]
        public DateTime PostedDate { get; set; }

        [JsonProperty("current_status")]
        public string CurrentStatus { get; set; }

        [JsonProperty("customer")]
        public Customer Customer { get; set; }

        [JsonProperty("application_address")]
        public ApplicationAddress ApplicationAddress { get; set; }


    }


public Class Customer
{

    public string name { get; set; }
    public string lastName { get; set; }
}

public classs ApplicationAddress
{
public string addreesLine1{ get; set; }
public string addreesLine1{ get; set; }
}

对于第一个响应,它将进行反序列化。但对于第二个响应,由于响应包含[]用于CustomerApplicationAddrees对象,因此响应未被反序列化。在反序列化时,它被视为数组,但实际上不是。
注意:我正在使用以下代码进行反序列化。 Response response = JsonConvert.DeserializeObject(result);
是否有任何配置可以在序列化之前进行?Newtonsoft是否提供该功能?
谢谢。

请问您能分享一下您的反序列化调用吗? - Timothée Bourguignon
针对不同的场景使用不同的类进行反序列化。第一个示例使用您已有的类,第二个示例使用带有List <Customer>,List <ApplicationAddresses>属性的类。您可以使用基类来共享属性。您正在调用单个终点吗? - Stephen Brickner
@TimBourguignon,我已经更新了问题,并附上了反序列化代码。 - PaRsH
@PaRsH 看起来又是我回答的另一个问题 - Arthur Rey
3个回答

1
如果您确定这些属性中不会有数组,那么可以考虑使用 JsonConverter,用法如下:
public class FakeArrayToNullConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return false;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return null;
        }
        return  token.ToObject<T>();

    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后将额外的属性添加到您的模型中:

    [JsonProperty("customer")]
    [JsonConverter(typeof(FakeArrayToNullConverter<Customer>))]
    public Customer Customers { get; set; }

    [JsonProperty("application_address")]
    [JsonConverter(typeof(FakeArrayToNullConverter<ApplicationAddress>))]
    public ApplicationAddress ApplicationAddressList { get; set; }

当您的 JSON 字符串中针对这些属性是一个数组 [] 时,您只需使用 null 对象进行反序列化。

0

你不能指示反序列化将 "[]" 解释为其他类型,因为它表示一个数组(你确定永远不会在这些数组中获取客户和地址吗??)

所以你可以反序列化为匿名类型,然后将其映射到你的结构。


是的,我确定我们不会得到一个客户数组。它将始终是一个单一的对象。 - PaRsH
好的,所以我会使用匿名函数来处理这种情况。 - tede24

0

这只是一个猜测,但你能否检查一下它是否有效:

public class ApplicationAddress
{
    private readonly string[] _array = new string[2];
    public string this[int index]
    {
        get { return _array[index]; }
        set { _array[index] = value; }
    }
    public string addreesLine1
    {
        get { return this[0]; }
        set { this[0] = value; }
    }
    public string addreesLine2
    {
        get { return this[1]; }
        set { this[1] = value; }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接