C# 将数据行转换为JSON对象
我有一个C# 将数据行转换为JSON对象,c#,.net,json,datatable,json.net,C#,.net,Json,Datatable,Json.net,我有一个DataTable,它只有一行,看起来像 America | Africa | Japan | ------------------------------------------------------------- {"Id":1,"Title":"Ka"} | {"Id":2,"Title":"Sf"} | {"Id":3,"Title":"Ja","Values":{"ValID":4,
DataTable
,它只有一行,看起来像
America | Africa | Japan |
-------------------------------------------------------------
{"Id":1,"Title":"Ka"} | {"Id":2,"Title":"Sf"} | {"Id":3,"Title":"Ja","Values":{"ValID":4,"Type":"Okinawa"}}
DataTable
列为美国、非洲、日本
现在我想将DataTable
转换为JSON,使JSON看起来像
{
"America": {
"Id": 1,
"Title": "Ka"
},
"Africa": {
"Id": 2,
"Title": "Sf"
},
"Japan": {
"Id": 3,
"Title": "Ja",
"Values": {
"ValID": 4,
"Type": "Okinawa"
}
}
}
我的尝试是:
string js = JSonConvverter.Serializeobject(datatable);
var objType = JObject.Parse(js);
但它不起作用。如有任何帮助,将不胜感激。拼写?对“SerializeObject”方法的调用不应该是:
string js = JsonConvert.SerializeObject(datatable);
还可以看到一个关于转换的类似问题。就像Gazzi说的那样,您应该包括Visual Studio中包含的NewtonSoft.Json库 要得到一个类似于您所描述的对象,您应该创建一个类似Country.cs的数据模型,该模型如下所示
[Serializable]
public class CountryModel {
public int ID { get; set; }
public string Title { get; set; }
public List<ValueModel> Values { get; set; }
}
[Serializable]
public class ValueModel {
public int ValueID { get; set; }
public string Type { get; set; }
}
[可序列化]
公共类模型{
公共int ID{get;set;}
公共字符串标题{get;set;}
公共列表值{get;set;}
}
[可序列化]
公共阶级价值模型{
public int ValueID{get;set;}
公共字符串类型{get;set;}
}
创建一个助手函数,将表数据转换为这些模型。然后,您可以根据需要使用Newtonsoft库对数据进行序列化/反序列化。假设您使用的是一个特殊的内置转换器,它以行数组的形式输出数据表,其中每一行都序列化为列名/值对,如您的问题所示。虽然也有,但没有特定的内置转换器。因此,当直接序列化DataRow
Json.NET时,将序列化DataRow
的所有字段和属性,从而产生更详细的输出-这是您不希望的
以DataTable
使用的更紧凑的形式序列化DataRow
最简单的方法是使用JArray
将整个表序列化为一个数组,然后选择与要序列化的DataRow
索引相同的数组项:
var rowIndex = 0;
var jArray = JArray.FromObject(datatable, JsonSerializer.CreateDefault(new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
var rowJToken = jArray[rowIndex];
var rowJson = rowJToken.ToString(Formatting.Indented); // Or Formatting.None if you prefer
因为您的表只有一行,rowIndex
应该是0
。更一般地说,如果您不知道给定数据行的索引,请参阅
演示小提琴#1
或者,如果您的表足够大,序列化整个表会影响性能,则可以引入forDataRow
,将该行作为对象写入JSON:
public class DataRowConverter : JsonConverter<DataRow>
{
public override DataRow ReadJson(JsonReader reader, Type objectType, DataRow existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException(string.Format("{0} is only implemented for writing.", this));
}
public override void WriteJson(JsonWriter writer, DataRow row, JsonSerializer serializer)
{
var table = row.Table;
if (table == null)
throw new JsonSerializationException("no table");
var contractResolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartObject();
foreach (DataColumn col in row.Table.Columns)
{
var value = row[col];
if (serializer.NullValueHandling == NullValueHandling.Ignore && (value == null || value == DBNull.Value))
continue;
writer.WritePropertyName(contractResolver != null ? contractResolver.GetResolvedPropertyName(col.ColumnName) : col.ColumnName);
serializer.Serialize(writer, value);
}
writer.WriteEndObject();
}
}
注:
- 虽然序列化单个
数据行
是有意义的,但反序列化一个数据行却没有意义,因为数据行
不是一个独立的对象;它只存在于某些父数据表中。因此,ReadJson()
没有实现
- Json.NET中引入了was。在早期版本中,继承自
Demo fiddle#2.作为找到答案的替代方法,您可以使用ExpandoObject
快速而轻松地将单行呈现为JSON,如下所示:
var expando=new System.Dynamic.ExpandoObject()作为IDictionary;
foreach(myRow.Table.Columns中的数据列col)
{
eo[col.ColumnName]=myRow[col];
}
var json=JsonConvert.SerializeObject(expando);
检查Json.NET
var row = datatable.Rows[rowIndex];
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Converters = { new DataRowConverter() },
};
var rowJson = JsonConvert.SerializeObject(row, Formatting.Indented, settings);