将 Json 个具有一个字段(对象类型)的对象转换为 json 个对象数组
Convert Json object with one filed(object type) into json array of objects
我是 C# 新手。我需要你的帮助。我有来自 Oracle 的 json 这样的:
[
{
"id": 123,
"name": "myname",
"avatars":[
{
"id": 1
"typeid": 500
},
{
"id": 2
"typeid": 600
}
]
}
]
但如果头像数组只有一行,Oracle returns 头像如下:
"avatars":{
"avatars_ROW":
{
"id": 1
"typeid": 500
}
}
现在 avatars 是一个 json 具有一个字段 _ROW 的对象,而不是 json 数组。
此外,我还有这样的其他字段(数组):"roles", "accounts"
... .
在 C# 中,我有所有列表,例如 List<avatar>
、List<role>
...
我的问题:
如何找到对象中第一个字段名称以“_ROW”结尾的所有字段,并将它们从具有一个字段(对象)的对象转换为具有一个成员的对象数组?
谢谢。
P.s。我无法更改 Oracle 的函数源代码。
这可能是完全错误的,但我认为您需要在序列化数据之前将其包装起来,如果您正在这样做的话。
所以您需要一个列表,当序列化为 json 时,您将在帐户中拥有一个列表,它应该是您想要的格式。
如果您查看一些带有包装器的 restsharp 示例,那么我认为这会有所帮助。
我无法改变 "desired format"。 Oracle 的函数 return 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 });
}
}
我是 C# 新手。我需要你的帮助。我有来自 Oracle 的 json 这样的:
[
{
"id": 123,
"name": "myname",
"avatars":[
{
"id": 1
"typeid": 500
},
{
"id": 2
"typeid": 600
}
]
}
]
但如果头像数组只有一行,Oracle returns 头像如下:
"avatars":{
"avatars_ROW":
{
"id": 1
"typeid": 500
}
}
现在 avatars 是一个 json 具有一个字段 _ROW 的对象,而不是 json 数组。
此外,我还有这样的其他字段(数组):"roles", "accounts"
... .
在 C# 中,我有所有列表,例如 List<avatar>
、List<role>
...
我的问题:
如何找到对象中第一个字段名称以“_ROW”结尾的所有字段,并将它们从具有一个字段(对象)的对象转换为具有一个成员的对象数组?
谢谢。
P.s。我无法更改 Oracle 的函数源代码。
这可能是完全错误的,但我认为您需要在序列化数据之前将其包装起来,如果您正在这样做的话。
所以您需要一个列表,当序列化为 json 时,您将在帐户中拥有一个列表,它应该是您想要的格式。
如果您查看一些带有包装器的 restsharp 示例,那么我认为这会有所帮助。
我无法改变 "desired format"。 Oracle 的函数 return 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 });
}
}