读取DataTable时出现意外的JSON令牌

时间:2018-09-18 07:47:31

标签: c# json datatable

我有以下json字符串:

{
    "Orders": [{
        "SubOrderNo": "0582715",
        "ItemNo": "20415541",
        "ItemType": "ART",
        "ItemName": "Fish",
        "TemplateName": "TP1234",
        "ObjectType": "MPP",
        "ObjectId": "PE1234",
        "SalesStartDate": "2018-08-01",
        "InfoText": "Some dummy text. This till be replaced later with some awesome text instead. Happy Fish!",
        "Attachment": null,
        "TemplateImage": null,
        "ApprovedBy": "Me",
        "ExpectedDeliveryDate": "2017-10-20",
        "Context": null,
        "TemplateDescription": null,
        "ColorStatus": 0,
        "spArticles": []
    }],
    "JsonOrders": null
}

我已经在json皮棉上对此进行了验证,因此它是有效的json。

我有以下代码:

 public static DataTable jsonStringToTable(string jsonContent)
    {
        DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
        return dt;
    }

运行此命令时,出现错误:

Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path '', line 1, position 1.

谁能告诉我为什么我不能将json转换为数据表?

4 个答案:

答案 0 :(得分:0)

因为您的对象是JSON数据中的复杂模型。您不能使用DataTable携带它。

所以我要编写模型类来携带它。

public class Order
{
    public string SubOrderNo { get; set; }
    public string ItemNo { get; set; }
    public string ItemType { get; set; }
    public string ItemName { get; set; }
    public string TemplateName { get; set; }
    public string ObjectType { get; set; }
    public string ObjectId { get; set; }
    public string SalesStartDate { get; set; }
    public string InfoText { get; set; }
    public object Attachment { get; set; }
    public object TemplateImage { get; set; }
    public string ApprovedBy { get; set; }
    public string ExpectedDeliveryDate { get; set; }
    public object Context { get; set; }
    public object TemplateDescription { get; set; }
    public int ColorStatus { get; set; }
    public List<object> spArticles { get; set; }
}

public class RootObject
{
    public List<Order> Orders { get; set; }
    public object JsonOrders { get; set; }
}

获取模型将是这样。

var result= JsonConvert.DeserializeObject<RootObject>(jsonContent);

如果要让JSON进入DataTable,则可以读取JSON密钥= Order

但如果您想"spArticles": []DeserializeObject,则DataTable会出现错误

[{
    "SubOrderNo": "0582715",
    "ItemNo": "20415541",
    "ItemType": "ART",
    "ItemName": "Fish",
    "TemplateName": "TP1234",
    "ObjectType": "MPP",
    "ObjectId": "PE1234",
    "SalesStartDate": "2018-08-01",
    "InfoText": "Some dummy text. This till be replaced later with some awesome text instead. Happy Fish!",
    "Attachment": null,
    "TemplateImage": null,
    "ApprovedBy": "Me",
    "ExpectedDeliveryDate": "2017-10-20",
    "Context": null,
    "TemplateDescription": null,
    "ColorStatus": 0,
    "spArticles": []  //<--- There will excute a error, I report for Json.net will be fixed in future.  
}]

https://github.com/JamesNK/Newtonsoft.Json/issues/1763


所以我建议您使用模型来承载json数据,而不要使用DataTable

答案 1 :(得分:0)

如果您不想映射对象,可以尝试以下方法:

string json = File.ReadAllText("bryan.json");
dynamic result = JsonConvert.DeserializeObject(json);
Console.WriteLine(result.Orders[0].ObjectId);

这将在不提供类的情况下创建对象,该类将以与js对象完全相同的方式动态分配属性

答案 2 :(得分:0)

使用这个,我希望它能起作用。

public static DataTable Tabulate(string jsonContent)
    {
        var jsonLinq = JObject.Parse(jsonContent);

        // Find the first array using Linq
        var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
        var trgArray = new JArray();
        foreach (JObject row in srcArray.Children<JObject>())
        {
            var cleanRow = new JObject();
            foreach (JProperty column in row.Properties())
            {
                // Only include JValue types
                if (column.Value is JValue)
                {
                    cleanRow.Add(column.Name, column.Value);
                }
            }

            trgArray.Add(cleanRow);
        }

        return JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());
    }

答案 3 :(得分:-1)

您需要先将json字符串反序列化为对象,然后使用该对象将其转换为数据表

public static DataTable jsonStringToTable(string jsonContent)
{
  dynamic jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonContent);
  DataTable dt = JsonConvert.DeserializeObject<DataTable>(Convert.ToString(jsonObject.Orders));
  return dt;
 }