2017-07-16 84 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' –