2015-03-03 109 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