0
[{"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 "}}]

I slimmed the object down alot. Basically when the '__type' is not in the first position, before 'id'. The deserialize will throw an error.

I have all the DataContract stuff setup correctly, with known types. I've tested in a console app, serializing, then taking that string back thru the deserialize and it works perfectly. The only difference is the location of the '__type'. This is a known MS issue. Documented at https://msdn.microsoft.com/en-us/library/bb412170(v=vs.110).aspx

Tried a string replace, which does work. and the DataContractJsonSerializer did not care if '__type' key was in there twice.

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

Just looking for the best way to move the __type to the first position.

Yogurt The Wise
  • 4,379
  • 4
  • 34
  • 42

2 Answers2

1

You can use Json.Net to manipulate your 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);

Output of this code is

[
  {
    "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 "
    }
  }
]

But I would recommend to use Json.Net all the way instead of just converting your json to the desired format.

L.B
  • 114,136
  • 19
  • 178
  • 224
  • This is a good solution, and others should try it first, if you have access to the newer version of json.net. Unfortunately, we have some old code relying on version 2.0, and change would cause major testing. – Yogurt The Wise Sep 12 '16 at 21:12
  • By experiment I have found that the JSON needs to be reserialized with `Newtonsoft.Json.Formatting.None`. Even having a space between the `{` and the `"__type"` will cause `DataContractJsonSerializer` to fail to process the type hint. – dbc Oct 03 '16 at 22:55
0

Besides the string replacement. I used an answer from Dave R - stack overflow

Use the JSON.stringify(obj, replacer array) replacer method.

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']);

Its a little bit of a pain to list all the keys, but it also acts like a filter, so i only return what i need as well. And since i put '__type' first, in all the objects and sub objects, this key was listed first after the stringify.

Community
  • 1
  • 1
Yogurt The Wise
  • 4,379
  • 4
  • 34
  • 42