2017-07-16 45 views
0

是否可以將JSON.NET生成的json與類型名稱處理設置爲常規json?將typenameHandling轉換爲常規json

我的應用程序不能假設任何關於它正在接收的類型,因爲它將是許多1000個類中的1個。我只需要從json中刪除類型信息。

比如我收到此JSON字符串在我的應用程序:

{ 
    "$type": "MyAssembly.MyType, MyAssembly", 
    "$id": 1, 
    "MyValue": 5 
} 

我可以把它轉換成此JSON:

{ 
    "MyValue": 5 
} 

我試圖加載原始JSON到JObject然後去除所有成員都以$開頭,但之後發現在使用陣列時失敗,因爲它們可能如下所示:

{ 
    "MyArray": { 
    "$type": "System.Collections.List, System", 
    "$values": [ 
     { 
     "$type": "MyAssembly.MyType, MyAssembly", 
     "MyValue": 5 
     } 
    ] 
    } 
} 

JSON.NET中是否有任何內容允許進行這種轉換?


這裏是爲了顯示我的意思

class Program 
{ 
    static void Main(string[] args) 
    { 
     JsonSerializerSettings withNamehandling = new JsonSerializerSettings() 
     { 
      TypeNameHandling = TypeNameHandling.All, 
      ReferenceLoopHandling = ReferenceLoopHandling.Serialize, 
      PreserveReferencesHandling = PreserveReferencesHandling.All, 
      Formatting = Formatting.Indented 
     }; 

     var obj = new MyObj(); 

     //This is the json which my application will be receiving. My application does not know about MyObj or MyType. 
     var json = JsonConvert.SerializeObject(obj, withNamehandling); 
     Console.WriteLine(json); 

     //Deserialize the object without namehandling enabled 
     var deserializeObject = JsonConvert.DeserializeObject(json); 
     //Serialize again without namehandling enabled 
     var json2 = JsonConvert.SerializeObject(deserializeObject, Formatting.Indented); 
     //Metadata removed from root node but not children. 
     Console.WriteLine(json2); 

     Console.ReadLine(); 
    } 
} 

class MyObj 
{ 
    public List<MyType> Types { get; set; } = new List<MyType>() 
    { 
     new MyType() 
     { 
      Value = 5 
     } 
    }; 
} 

class MyType 
{ 
    public int Value { get; set; } 
} 
+0

你想怎麼辦'PreserveReferencesHandling'令牌什麼樣'「$ ID」'和'「$ REF」'?第一個''$ id「'很容易刪除,但第二個是有問題的,因爲''$ ref」'只是一個指向JSON層次結構其他地方的指針。在您的問題的原始版本中,並沒有要求移除'PreserveReferencesHandling'令牌,但您似乎在更新中添加了它,使其更加複雜。 – dbc

回答

0

如果我使用http://json2csharp.com/,下面的結構,我得到

public class RootObject 
{ 
    public string __invalid_name__$type { get; set; } 
    public int __invalid_name__$id { get; set; } 
    public int MyValue { get; set; } 
} 

有了,如果您創建模型

內容示例
public class MyType 
{ 
    public int MyValue { get; set; } 
} 

而且ñ它反序列化到該類型MyType

您可以如用JsonProperty註釋,使不需要特定的屬性一樣

public class RootObject 
{ 
    [JsonProperty(Required = Required.Default)] 
    public string __invalid_name__$type { get; set; } 
    [JsonProperty(Required = Required.Default)] 
    public int __invalid_name__$id { get; set; } 
    public int MyValue { get; set; } 
} 
+0

我需要刪除任何* json.net序列化json的類型信息,然後纔將其推送到外部應用程序。我不知道json包含的實際類型,所以這不是一個選項。我只需要刪除json.net元信息。 –

+0

@NickWilliams,如果有幫助,請參閱編輯答案。同時發佈你的代碼,如何反序列化它 – Rahul

+0

我不認爲這有幫助。我的應用程序沒有「MyType」的知識,所以我無法爲它創建類。我只需要刪除元數據。新增示例程序,以備有用時 –

0

是的,你可以反序列化的數據,然後重新序列化它。默認情況下,JSON .NET將不包含類型名稱,所以必須由序列化端設置目的,以使用相同的程序集來序列化/反序列化數據,所以在不使用真實源程序集的情況下操作數據時要小心。

總之,反序列化數據首先創建與真實數據擬合的模型:

public class RootObject 
{ 
    public List<MyObject> MyArray { get; set; } 
} 

public class MyObject 
{ 
    public MyType MyValue { get; set; } 
} 

//I assume this because there's not info about "MyType" 
public class MyType : String { } 

現在你創建一個JsonSerializerSettings並設置TypeNameHandlingNone

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None }; 

和反序列化的數據到您的結構:

var deser = JsonConvert.DeserializeObject<RootObject>(seria, settings); 

現在你有數據重建,你可以沒有類型處理重新序列化它,它會刪除所有的命名空間和類的類型:

var cleanJson = JsonConvert.SerializeObject(deser, settings); 

編輯:

如果你並不需要重建結構只需使用設置,張貼和德/序列化到JObject:

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None }; 
var deser = JsonConvert.DeserializeObject(SourceData, settings); 
var clean = JsonConvert.SerializeObject(deser, settings); 
+0

查看更新。我的應用程序不能假設它正在接收的類型,它將是許多1000個類中的1個。我只需要從json中刪除類型信息。 –

+0

@NickWilliams查看我的更新。如果你有嚴格的要求,最好在問題上解釋他們。 – Gusman

+0

我以爲我已經說清楚了,但顯然我沒有。無論如何,您的編輯會提供與我的示例相同的結果,這會在陣列上留下所有類型信息。所以數組仍然分爲'$ type'和'$ array' –