JSON.NET:如何在没有数组的情况下从DataTable对象中仅序列化一行?

时间:2017-04-10 05:41:40

标签: c# json json.net

我有一个调用数据库并检索数据的数据库类。数据将加载到DataTable对象中,并带有SqlDataAdapter。然后我想只获取第一行数据(事实上,数据库只会返回一行)并将其转换为JSON字符串。

问题在于:如果我只是将DataTable传递给JsonConvert.SerializeObject方法,例如JsonConvert.SerializeObject(dt),我得到一个JSON字符串,但它是一个包含一个对象的数组。例如:

[ {"id":"1","value":"hi"} ]

另一端希望接收此JSON的代码不需要数组,它只需要一个对象。所以基本上我需要上面的内容,但没有方括号[]。所以期望的输出是:

{"id":"1","value":"hi"}

我现在使用的天真方法是将result.Substring(1,result.Length - 2)返回给调用者。假设JSON对象只存在于一个对象的单个数组中,这样可以从返回文本中删除[]。但似乎应该有一种“适当”的方式来实现这一目标。

最显而易见的事情似乎是使用DataTable的Rows属性。但是,如果我尝试JsonConvert.SerializeObject(dt.Rows[0]),我不会得到行,我得到关于行状态的整个数据集合,其中一个项目为Table,但它只是引用了整个表,所以如果发生多行,我会得到所有的行,而不仅仅是我想要的行。

我尝试过的另一种方法是从整个DataTable往返JSON。我序列化了DataTable,然后将结果解析为JArray,这样我就可以得到第一个值,然后再次重新序列化。但这似乎没必要。

以下是尝试序列化Row对象的原因:

{
    "RowError":"",
    "RowState":2,
    "Table":[
        {
            "id":"1",
            "value":"hello"
        }
    ],
    "ItemArray":[
        "1","hello"
    ],
    "HasErrors":false
}

我是否能以“正确”的方式执行此操作,而不仅仅从字符串中删除[]?换句话说,我是否可以将DataTable的一行中的数据作为单个JSON对象获取,而不是在数组中,而不是通过JSON进行往返,而只是从单项数组中取出它?

2 个答案:

答案 0 :(得分:9)

您可以使用LINQ-to-JSON APIJObject建立DataRow。例如:

DataTable dt = new DataTable();
dt.Columns.Add("id");
dt.Columns.Add("value");
dt.Rows.Add("1", "hi");

string json = new JObject(
    dt.Columns.Cast<DataColumn>()
      .Select(c => new JProperty(c.ColumnName, JToken.FromObject(dt.Rows[0][c])))
).ToString(Formatting.None);

Console.WriteLine(json);

输出:

{"id":"1","value":"hi"}

小提琴:https://dotnetfiddle.net/ndL1xu

答案 1 :(得分:0)

只要你只从查询/ DataTable接收一行,在JSON.Net中你可以使用一个私有的setter接受Table结构作为List和一个只返回第一行的公共属性像这样的对象:

using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;

public class DataTableToModel
{
    /// <summary>
    /// Deserialize from DataTable, set ModelProperty from first row
    /// </summary>
    [JsonProperty("Table")]
    private List<Model> ModelSetter { set { this.ModelProperty = value.FirstOrDefault(); } }

    /// <summary>
    /// Serialize Model
    /// </summary>
    [JsonProperty("Model")]
    public Model ModelProperty { get; set; }
}

/// <summary>
/// Model that has id and value properties expected from DataTable
/// </summary>
public class Model 
{
    [JsonProperty("id")]
    public string id { get; set; }

    [JsonProperty("value")]       
    public string value { get; set; }
}

要利用它,您需要将DataTable添加到DataSet,将JsonConvert.SerializeObject添加到DataSet,然后将ModelProperty对象上的JsonConvert.DeserializeObject添加到这样:

DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.TableName = "Table";
dt.Columns.Add("id");
dt.Columns.Add("value");
dt.Rows.Add("1", "hi");
ds.Tables.Add(dt);

var dsString = JsonConvert.SerializeObject(ds);     
var model = JsonConvert.DeserializeObject<DataTableToModel>(dsString);              
var json = JsonConvert.SerializeObject(model.ModelProperty);

以下是dotnetfiddle示例。