如何让json中的__type键成为DataContractJsonSerializer的第一个

时间:2016-09-09 19:37:02

标签: c# json deserialization datacontract

[{"id":"PROCESS_ROOT_NODE","text":"TEMPLATE - 3333(2)","icon":"fa fa-list fa-color-graylt","li_attr":{"id":"PROCESS_ROOT_NODE","__type":"li_attr:#SomeNamespace.JsonDataContractClasses","class":" ps_node_li "}}]

我把这个物体缩小了很多。 基本上当' __类型'在&id;之前不是第一个位置。反序列化将引发错误。

我已经使用已知类型正确设置了所有DataContract内容。 我已经在控制台应用程序中进行了测试,序列化,然后通过反序列化将该字符串恢复,并且它完美地运行。唯一的区别是' __ type'的位置。这是一个已知的MS问题。 记录在https://msdn.microsoft.com/en-us/library/bb412170(v=vs.110).aspx

尝试了一个字符串替换,它确实有效。并且DataContractJsonSerializer并不关心' __ type'钥匙在那里两次。

 content = content.Replace("\"li_attr\":{", "\"li_attr\":{\"__type\":\"li_attr:#Payce.Common.AnonymousClasses.JsonDataContractClasses\",");

只是寻找将__type移动到第一个位置的最佳方法。

2 个答案:

答案 0 :(得分:1)

您可以使用Json.Net来操纵您的json

var jArr = JArray.Parse(jsonstring);
var attrs = jArr.Select(x => x["li_attr"]).ToList();
attrs.ForEach(attr =>
{
    var type = attr["__type"].Parent;
    type.Remove();
    (attr as JObject).AddFirst(type);
});
var newjson = jArr.ToString(Newtonsoft.Json.Formatting.Indented);

此代码的输出为

[
  {
    "id": "PROCESS_ROOT_NODE",
    "text": "TEMPLATE - 3333(2)",
    "icon": "fa fa-list fa-color-graylt",
    "li_attr": {
      "__type": "li_attr:#SomeNamespace.JsonDataContractClasses",
      "id": "PROCESS_ROOT_NODE",
      "class": " ps_node_li "
    }
  }
]

但我建议一直使用Json.Net,而不是仅仅将json转换为所需的格式。

答案 1 :(得分:0)

除了字符串替换。 我使用了Dave R - stack overflow

的答案

使用JSON.stringify(obj,replacer array)替换方法。

var json = JSON.stringify(o, ['__type', 'id', 'parent', 'text', 'type', 'children', 'data', 'li_attr', 'a_attr', 'state', 'class', 'descr', 'display_priority', 'action_area_id', 'action_user_type_id']);

列出所有键有点痛苦,但它也像过滤器一样,所以我只返回我需要的东西。 因为我把' __ type'首先,在所有对象和子对象中,在stringify之后首先列出了该键。