簡體   English   中英

.NET 序列化 JSON 數據的動態結構(模式)

[英].NET serialization of JSON data with dynamic structure (schema)

web 服務我使用 json 數據進行響應。

如果有多個 object,它將 resultObject 作為數組提供: resultObject:[{object1}, {object2},...]如果只有一個 object,則返回resultObject:{object1 }。

為了在 .NET 中序列化,我為 map json 模式創建了一個“靜態”類結構。 但是,如果在一種情況下我有一個對象數組(列表),而在另一種情況下只有一個 object,如何處理這種情況?

我已經找到了很多丑陋的解決方案,但到目前為止:

如果您使用System.Web.Script.Serialization.JavaScriptSerializer您的控制非常有限。 如果結果數據類型很簡單,你可以簡單地使用DeserializeObject方法; 它將所有內容翻譯成字典,並且“resultObject”屬性在第一種情況下將是字典,而后一種情況會將其轉換為此類字典的數組。 它不會為您省去最終翻譯的麻煩,但您會將數據放入字典中,這可以被認為是第一步。

我還嘗試使用 KnownTypes 和 DataContractJsonSerializer,但可惜 datacontract 序列化程序需要特殊命名屬性形式的“提示”來幫助它反序列化。 為什么我錯誤地使用了 KnownType 屬性? )。 如果您對序列化沒有任何控制權,這是一個無望的策略,我猜您就是這種情況。

因此,現在我們要考慮最丑陋的解決方案,其中試錯是我的首選:使用 ScriptSerializer 時,如果出現任何錯誤,轉換將失敗並返回 InvalidOperationException。 然后,我創建了兩種數據類型,一種是數據作為數組,另一種是數據是單個實例(DataClass 是我的發明,因為您沒有指定數據類型):

    [DataContract]
    public class DataClass
    {
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public int BirthYear { get; set; }

        public override string ToString()
        {
            return "FirstName : '" + FirstName + "', BirthYear: " + BirthYear;
        }
    }

    [DataContract]
    public class ResultSingle 
    {
        [DataMember]
        public DataClass Data { get; set; }
    }

    [DataContract]
    public class ResultArray 
    {
        [DataMember]
        public List<DataClass> Data { get; set; }
    }

使用這些數據類型,可以使用

        JavaScriptSerializer jSer = new JavaScriptSerializer();
        var one = jSer.Deserialize<ResultSingle>(jsonWithSingleInstance);
        var many = jSer.Deserialize<ResultArray>(jsonWithArray);

但這當然需要您提前知道數據類型,並且您會得到兩種不同的結果類型。 相反,您可以選擇始終轉換為 ResultArray。 如果遇到異常,應轉換為 ResultSingle,然后實例化 ResultArray 並手動將數據 object 添加到數據列表中:

    static ResultArray ConvertJson(string json)
    {
        ResultArray fromJson;
        JavaScriptSerializer jSer = new JavaScriptSerializer();
        try
        {
            fromJson = jSer.Deserialize<ResultArray>(json);
            return fromJson;
        }
        catch (InvalidOperationException)
        {
            var single = jSer.Deserialize<ResultSingle> (json);
            fromJson = new ResultArray();
            fromJson.Data = new List<DataClass>();
            fromJson.Data.Add(single.Data);
            return fromJson;
        }
    }

    static void Main(string[] args)
    {
        var jsonWithSingleInstance = "{\"Data\":{\"FirstName\":\"Knud\",\"BirthYear\":1928}}";
        var jsonWithArray = "{\"Data\":[{\"FirstName\":\"Knud\",\"BirthYear\":1928},{\"FirstName\":\"Svend\",\"BirthYear\":1930}]}";

        var single = ConvertJson(jsonWithSingleInstance);
        var array = ConvertJson(jsonWithArray);
    }

我並不是說這是一個漂亮的解決方案(它不是),但它應該可以完成這項工作。

You could also look at json.net which seem to be the json serializer of choice in .NET: How to install JSON.NET using NuGet?

嗯,我的服務商最后說真的是bug。

http://jira.codehaus.org/browse/JETTISON-102

說那是因為他們使用的 java 版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM