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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSON.NET:如何在没有数组的情况下从DataTable对象中仅序列化一行?相关的知识,希望对你有一定的参考价值。

我有一个数据库类,它调用数据库并检索数据。使用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进行往返,而只是从单项数组中取出它?

答案

你可以使用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

另一答案

只要你只从查询/ 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的例子。

以上是关于JSON.NET:如何在没有数组的情况下从DataTable对象中仅序列化一行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 OutOfMemory 错误的情况下从 FileInputStream 获取字节数组

如何在没有任何循环php的情况下从数组中随机获取项目

如何在没有 I/O 的情况下从字节数组保存数据时使用 dlib 人脸检测?

如何在没有 Jmeter 中的 foreach 控制器的情况下从数组中提取值(通过 JSON 提取器获得)

如何在没有动画的情况下从集合视图中删除项目?

如何在没有 numpy 或 pandas 的情况下从文本文件计算平均值