您将需要一个自定义 DataTable 转换器来完成此操作。我改编了this answer中的那个。
主要思路是检测属性是否包含if (rowDataObj[col.ColumnName].Type == JTokenType.Array)的数组。在这种情况下,我们只需使用.ToString() 来保留原始字符串。
class Program
{
static void Main(string[] args)
{
var json = @"[{""Name"":""John"",""Age"":""22"",""Json"":[{""Prop"":1}]},"
+ @"{""Name"":""Eric"",""Age"":""25"",""Json"":[{""Prop"":2}]},"
+ @"{""Name"":""Joan"",""Age"":""38"",""Json"":[{""Prop"":3}]}]";
var table = JsonConvert.DeserializeObject<DataTable>(json,
new CustomDataTableConverter());
foreach (DataRow row in table.Rows)
{
Console.WriteLine($"{row["Name"]}, {row["Age"]}, {row["Json"]}");
}
}
}
public class CustomDataTableConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => (objectType == typeof(DataTable));
public override bool CanWrite => false;
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
var rowsArray = JArray.Load(reader);
var metaDataObj = (JObject)rowsArray.First();
var dt = new DataTable();
foreach (var prop in metaDataObj.Properties())
{
dt.Columns.Add(prop.Name);
}
foreach (JObject rowDataObj in rowsArray)
{
var row = dt.NewRow();
foreach (DataColumn col in dt.Columns)
{
if (rowDataObj[col.ColumnName].Type == JTokenType.Array)
{
row[col] = rowDataObj[col.ColumnName].ToString(Formatting.None);
}
else
{
row[col] = rowDataObj[col.ColumnName].ToObject(col.DataType);
}
}
dt.Rows.Add(row);
}
return dt;
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
结果是:
John, 22, [{"Prop":1}]
Eric, 25, [{"Prop":2}]
Joan, 38, [{"Prop":3}]