反序列化JSON时如何删除或忽略Java类型提示?

时间:2015-07-21 17:35:49

标签: java c# json json.net

我正在构建一个需要从第三方Web服务中使用JSON的C#应用​​程序。看来第三方正在使用Java来生成JSON,因为返回的字符串中有Java类型信息(例如,下面的“com.company.RegistrationDetail”)。具体而言,复杂对象以“@type”属性开头:

...
"registration": {
    "@type": "com.company.RegistrationDetail",
    "id": "regdw000000000003551",
    "displayName": "Registration 3551"
},
...

显然,这个“@type”值在C#中对我没用。因为它只是一个属性,所以很容易忽略。数组是另一回事:

...
"warnings": [
    "java.util.ArrayList",
    [
        "Warning #1",
        "Warning #2"
    ]
],
...

“warnings”数组表示为包含类型名称的字符串,然后是带有实际警告项的嵌套数组。这会干扰我的反序列化器(JSON.NET),因为“警告”中的项目类型不一致。

我可以将JSON的每个块反序列化为JObject或JArray,但这将非常繁琐,因为Web服务的输出非常复杂,具有许多级别的嵌套对象和数组。理想情况下,我希望能够使用json2csharp之类的东西从JSON输出生成C#类,然后一次反序列化所有内容,如:

JsonConvert.DeserializeObject<GeneratedResponseClass>(jsonResponseData);

这是Java中众所周知的编码技术(即将类型信息嵌入到JSON中)吗?在C#中反序列化JSON时,有没有办法去掉或忽略这个Java类型信息?

这是一个更完整的示例(删除了许多多余的属性和嵌套对象)。我想获得orderDetail的价值 - &gt; orderItems [0] - &gt;注册 - &gt;标识。

{
    "@type":"com.company.learning.services.registration.OrderResult",
    "orderId":"intor000000000004090",
    "orderDetail":{
        "@type":"com.company.learning.services.registration.OrderDetail",
        "orderStatus":"Confirmed",
        "orderItems":[
            "list",
            [
                {
                    "@type":"com.company.learning.services.registration.OrderItemDetail",
                    "registration":{
                        "@type":"ServiceObjectReference",
                        "id":"regdw000000000003551",
                        "displayName":""
                    },
                    "quantity":null,
                    "itemStatusDescription":"Registered"
                }
            ]
        ],
        "orderContact":"Sample Person",
        "orderNumber":"00003911",
        "orderDate":{
            "@type":"com.company.customtypes.DateWithLocale",
            "date":1437425816000,
            "locale":"20-JUL-2015",
            "timeInUserTimeZone":"3:56 PM",
            "timeInCustomTimeZone":null,
            "dateInCustomTimeZone":null,
            "customTimeZoneDate":0,
            "timeInLocale":"4:56 PM",
            "dateInUserTimeZone":"20-JUL-2015"
        }
    }
}

1 个答案:

答案 0 :(得分:1)

根据你的最终json,你的模型将是:

public class Registration
{
    public string id { get; set; }
    public string displayName { get; set; }
}

public class Order
{
    public Registration registration { get; set; }
    public object quantity { get; set; }
    public string itemStatusDescription { get; set; }
}

public class OrderDate
{
    public long date { get; set; }
    public string locale { get; set; }
    public string timeInUserTimeZone { get; set; }
    public object timeInCustomTimeZone { get; set; }
    public object dateInCustomTimeZone { get; set; }
    public int customTimeZoneDate { get; set; }
    public string timeInLocale { get; set; }
    public string dateInUserTimeZone { get; set; }
}

public class OrderDetail
{
    public string orderStatus { get; set; }
    public List<Order> orderItems { get; set; }
    public string orderContact { get; set; }
    public string orderNumber { get; set; }
    public OrderDate orderDate { get; set; }
}

public class RootObject
{
    public string orderId { get; set; }
    public OrderDetail orderDetail { get; set; }
}

这是Converter类

public class JavaArrayConverter : JsonConverter
{
    Type _Type = null;
    public override bool CanConvert(Type objectType)
    {
        if(objectType.IsGenericType)
        {
            _Type = typeof(List<>).MakeGenericType(objectType.GetGenericArguments()[0]);
            return objectType == _Type;
        }
        return false;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jArray = JArray.Load(reader);
        return jArray[1].ToObject(_Type); //jArray[0] is the "java-type"
    }

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

现在您可以反序列化为:

var root = JsonConvert.DeserializeObject<RootObject>(DATA, new JavaArrayConverter());