DataTable
がありますが、これは1行しかなく、次のようになります。
America | Africa | Japan |
-------------------------------------------------------------
{"Id":1,"Title":"Ka"} | {"Id":2,"Title":"Sf"} | {"Id":3,"Title":"Ja","Values":{"ValID":4,"Type":"Okinawa"}}
DataTable
列は、アメリカ、アフリカ、日本です。
次に、JSONが次のようになるようにDataTable
を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);
しかし、それはうまくいきませんでした。どんな助けでもいただければ幸いです。
json.net を使用していると仮定すると、特別な組み込みコンバーター DataTableConverter
があり、データテーブルを 省略形式で出力します 各行が次のようにシリアル化される行の配列として質問に示されている列名と値のペア。 DataSet
用のコンバーターもありますが、 DataRow
用の特定の組み込みコンバーターはありません。したがって、DataRow
を直接シリアル化する場合、Json.NETはDataRow
のすべてのフィールドとプロパティをシリアル化するため、より詳細な出力が得られます。これは望ましくありません。
DataRow
で使用されるよりコンパクトな形式でDataTable
をシリアル化する最も簡単な方法は、 JArray.FromObject()
を使用してテーブル全体を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
テーブルには1行しかないため、rowIndex
は0
である必要があります。より一般的には、特定のDataRow
のインデックスがわからない場合は、データテーブルから行番号を取得する方法を参照してください。。
デモフィドル#1 ここ 。
あるいは、テーブル全体をシリアル化するとパフォーマンスに影響するほどテーブルが大きい場合は、 カスタムJsonConverter
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();
}
}
そして、次のように使用します。
var row = datatable.Rows[rowIndex];
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Converters = { new DataRowConverter() },
};
var rowJson = JsonConvert.SerializeObject(row, Formatting.Indented, settings);
ノート:
単一のDataRow
をシリアル化することは理にかなっていますが、DataRow
はスタンドアロンオブジェクトではないため、 deserialize 1つをシリアル化することは意味がありません。親DataTable
内にのみ存在します。したがって、ReadJson()
は実装されていません。
JsonConverter<T>
はJson.NETで導入されました 11.0.1 。以前のバージョンでは、 JsonConverter
から継承します。
デモフィドル#2 ここ 。
Gazziが言ったように、VisualStudioに含まれている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; }
}
テーブルデータをこれらのモデルに変換するヘルパー関数を作成します。その後、Newtonsoft Libraryを使用して、必要に応じてデータをシリアル化/逆シリアル化できます。
つづり? 「SerializeObject」メソッドの呼び出しは次のようにすべきではありません。
string js = JsonConvert.SerializeObject(datatable);
データテーブルをJSON文字列に変換する の変換に関する同様の質問も参照してください。