2015-09-04 20 views
1

我正在使用.NET的JavaScriptSerializer反序列化可以是你的標準平鍵/值對這樣的結構反序列化內部結構到字符串JavaScriptSerializer:在.NET

{ 
    "Value": 3.14, 
    "Type": "Real" 
} 

或更復雜的,具有內分層值對象是這樣的:

{ 
    "Value": { "something": "test" }, 
    "Type": "JsonData" 
} 

我的問題是,在"Type": "JsonData"的情況下,該對象可以是任意的。我不能假設它的結構會是什麼。

但是,我的應用程序的「上層」會知道如何處理這些數據。

因此,我需要找出一種方法來保持字段的字符串,無論它是否包含整數,字符串或完整的JSON結構。基本上,我不希望JavaScriptSerializer解析那裏的任何東西。我希望能有這樣一個類:

public class JsonObject 
{ 
    public string Value { get; set; } 
    public string Type { get; set; } 
} 

隨着Value包含在我的JSON未處理,香草值。

有什麼辦法可以告訴.NET不要解析我的JSON的一部分?

建議不要使用其他圖書館一樣JSON.NET。我知道它可能會做到這一點,但這是一個將作爲庫分發的項目 - 這就是爲什麼我寧願讓我的庫僅依賴於標準的.NET框架。

+1

我必須說** ** JSON.Net提供最好的'json'解析庫。 –

+0

我知道,我已經在很多其他項目中多次使用過它:)但是,對於我的項目來說,這完全是過度的,我真的必須要做的是標準的.NET運行時提供的東西,除此之外! –

+1

ASP.NET MVC *也*使用Json.Net,這應該滿足要求。 「作爲一個庫」的要求並不意味着你不能使用Json.NET。這並不過分,它比過時的JavaScriptSerializer更簡單,更簡單,更合規。 –

回答

1

沒有指示JavaScriptSerializer不能解析特定的JSON屬性(而不是完全忽略它,這是不是你想要的除外)的屬性。但是,您可以創建一個JavaScriptConverter,這將有效地重新序列化所討論的屬性,以便您仍然可以獲得所需的結果:所有值都以字符串形式結尾。

這裏是轉換器可能是什麼樣子:

public class JsonObjectConverter : JavaScriptConverter 
{ 
    public override IEnumerable<Type> SupportedTypes 
    { 
     get { return new List<Type> { typeof(JsonObject) }; } 
    } 

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) 
    { 
     JsonObject obj = new JsonObject(); 
     obj.Type = (string)dictionary["Type"]; 
     obj.Value = serializer.Serialize(dictionary["Value"]); 
     return obj; 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

要使用轉換器,必須使用RegisterConverters方法與JavaScriptSerializer註冊。這裏是一個演示:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @" 
     [ 
      { 
       ""Value"" : ""foo bar"", 
       ""Type"" : ""String"" 
      }, 
      { 
       ""Value"" : 3.14, 
       ""Type"" : ""Real"" 
      }, 
      { 
       ""Value"" : 
       { 
        ""Something"" : ""Test"", 
        ""Items"" : [""A"", ""B"", ""C""] 
       }, 
       ""Type"" : ""JsonData"" 
      }, 
      { 
       ""Value"" : 42, 
       ""Type"" : ""Integer"" 
      } 
     ]"; 

     JavaScriptSerializer jss = new JavaScriptSerializer(); 
     jss.RegisterConverters(new List<JavaScriptConverter> { new JsonObjectConverter() }); 

     List<JsonObject> list = jss.Deserialize<List<JsonObject>>(json); 
     foreach (JsonObject item in list) 
     { 
      Console.WriteLine(string.Format("({0}) {1}", item.Type, item.Value)); 
     } 
    } 
} 

public class JsonObject 
{ 
    public string Value { get; set; } 
    public string Type { get; set; } 
} 

輸出:

(String) "foo bar" 
(Real) 3.14 
(JsonData) {"Something":"Test","Items":["A","B","C"]} 
(Integer) 42 
+0

感謝您的解決方案!在這段時間裏,我決定按照你的建議重新序列化。儘管沒有轉換器。儘管你的解決方案有點乾淨! –

0

嘗試這樣的:

public class JsonObject 
{ 
    public object Value { get; set; } 
    public object Type { get; set; } 
} 
+0

謝謝,我已經試過了,是的,它正確地反序列化。然而,我遇到的問題是我真的需要Value作爲一個字符串而不是一個對象。這是我的代碼的上半部分期望! –

+1

你的要求有點奇怪。 Plus「帶有」Value「:3.14','Value'不是'string'。 –

+0

我知道這不是一個字符串。我說的是,上層會知道如何處理''「3.14」''或''「\」Hello \「」'' –