2015-03-03 50 views
0

我是C#中的新成员。我需要你的帮助。我已经JSON像这样从Oracle:将Json对象与一个提交的(对象类型)转换为json数组对象

[ 
    { 
    "id": 123, 
    "name": "myname", 
    "avatars":[ 
     { 
     "id": 1 
     "typeid": 500 
     }, 
     { 
     "id": 2 
     "typeid": 600 
     } 
    ]  
    } 
] 

但如果化身阵列只有一行,Oracle返回的化身,如:

"avatars":{ 
    "avatars_ROW": 
     { 
     "id": 1 
     "typeid": 500 
     } 
} 

现在身形是有一个字段_ROW,不是JSON数组JSON对象。

此外,我还有其他领域(阵列)像这样:"roles", "accounts" ...。

在C#中我都列出像List<avatar>List<role> ...

我的问题:

如何找到对象的所有字段,第一个字段的名称以“_ROW”结束,将它们从一个字段(对象)转换为一个成员的对象数组?

谢谢。

P.s.我无法更改Oracle的函数源代码。

+0

那么,你会为它编写代码。 “头像”会给你一个数组或字典。所以你检查它是否返回了一个字典,并编写代码将这个字典转换为一个数组。 – gnasher729 2015-03-03 10:13:55

+0

谢谢。我如何检查字典或不?对不起,我是从德尔福来的。那里工作与json是完全不同的 – 2015-03-03 10:24:38

+0

你能否更详细地解释一下? – 2015-03-03 14:48:11

回答

0

我无法更改“所需的格式”。 Oracle的函数为我返回json。
我公司创建愚蠢的解决方案,但它的工作原理:)
这是我的职责纠正JSON:

// fix _ROW in "pretty-print :)" json text 
static private String FixJson(String json) 
{ 
    const String cRowString = "_ROW\" : {";  // _ROW" : {" 
    const String cEmpArrInvalid = "\" : \"\\n \""; // " : "\ " 
    const String cEmpArrNormaly = "\":[]";   // ":[] 

    var lines = json.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); // json-string to string array. delimiter = NewLine 
    for (var i = 0; i < lines.Count(); i++) // loop strings 
    { 
     var line = lines[i]; // current string 

     // oracle return json array with count=0 as "blabla": "\ ". I need "blabla": [] 
     char[] charsToTrim = { ',' }; 
     if (line.TrimEnd(charsToTrim).EndsWith(cEmpArrInvalid)) // find jarray-value with 0 elements. fucking Oracle's function :) 
     { 
      lines[i] = line.Replace(cEmpArrInvalid, cEmpArrNormaly); // replace bad substring("\ ") on empty array([]) 
      continue; // next string 
     } 

     if (!line.Contains(cRowString)) continue; // if not bad-string => next string 

     lines[i - 1] = lines[i - 1].Replace("{", "["); // _ROW found => in prev string replace object's start ({) on array's start ([) 
     var pStart = line.IndexOf("\"", StringComparison.CurrentCulture); // find start position of field (") 

     var sFind = ""; // string to search for end of object = backspace*pStart + } 
     for (var k = 0; k < pStart; k++) 
      sFind = sFind + ' '; 
     sFind = sFind + '}'; 

     lines[i] = "{"; // replace singl-row property "blablabla_ROW": { on start of object ({) 

     for (var j = i + 1; j < lines.Count(); j++) // from next line, find end of object. and replace object's end on array's end 
     { 
      if (!lines[j].StartsWith(sFind)) continue; // if not end of object then next string 

      lines[j + 1] = lines[j + 1].Replace("}", "]"); // found ! replace object's end on array's end 
      break; // break loop 
     } 
    } 

    return String.Join(Environment.NewLine, lines); // join string array into one string with newline-separator 
} 

,但想通过图书馆json.net的手段来解决这个问题,不分析\变线。

我解决了这个问题。我的功能:

private static void FixJObj(JToken jt) 
{ 

    if (jt.GetType() == typeof (JArray)) 
    { 
     foreach (var item in (JArray) jt) 
     { 
      FixJObj(item); 
     } 
     return; 
    } 

    if (jt.GetType() != typeof(JObject)) return; 

    var jo = (JObject) jt; 

    foreach (var jField in jo) // loop in object fields 
    { 
     if (jField.Value.ToString() == "\n ") // if field value = "\n " 
     { 
      jField.Value.Replace(new JArray()); // replace "\n " with empty array [] 
      continue; 
     } 

     if ( !jField.Value.Any() ) continue; 

     FixJObj(jField.Value); // fix cur obj field recursive 

     var jFirstField = jField.Value.First; // get first field 
     if (jFirstField.GetType() != typeof(JProperty)) continue; // if its property 

     var jProp = ((JProperty)jFirstField); 

     if (!jProp.Name.EndsWith("_ROW")) continue; 

     jField.Value.Replace(new JArray { jProp.Value }); 
    } 
} 
0

也许有这个完全错误的,但我认为你需要你的序列数据之前,如果这是你在做什么来包装它。

所以你需要一个列表,并在帐户你将有一个列表时,这是序列化到JSON,它应该是你想要的格式。

如果你看看与包装一些restsharp例子那么我认为这将有助于。

+0

我无法更改“所需的格式”。 Oracle的函数为我返回json。 – 2015-03-04 07:04:59