【问题标题】:How to parse SQL JSON string in C# in asp.net mvc web api?如何在asp.net mvc web api中解析C#中的SQL JSON字符串?
【发布时间】:2022-01-08 18:05:25
【问题描述】:

我在 asp.net mvc 中创建了 web api,我正在调用 usp_JsonPract 这个 SP,它从 DB 返回 JSON 字符串,现在我在 .net mvc web api 上转换这个字符串时遇到问题。

我的存储过程代码:

    Create proc [dbo].[usp_JsonPract]
    as
    BeginSelect  category title
        ,[data] = JSON_QUERY(
                    (
                    select din.dishId,din.dishName,din.dishPrice,din.dishImage, din.dishType,
                    JSON_QUERY(dishPriceAndSize, '$.dishPriceAndSize') AS dishPriceAndSize, 
                    JSON_QUERY(JAddOns, '$.addOns') AS addOns, 
                    din.includedEggs, din.dishDescription, din.rating, din.review,din.discount
                    from DishMaster din 
                    where din.category = dout.category 
                    --and dishId in ( 11, 12,13 , 7  )
                    for json path
                    ,INCLUDE_NULL_VALUES
                    )
                  )from DishMaster dout 
    group by category 
    for json path,without_array_wrapper

存储过程正在返回我想要传递给客户端的 JSON 字符串。我正在使用JsonConvert.DeserializeObject(jsonstr); 进行转换。

我的 C# 代码:

    public object SQLJSONPract()
    {
        string jsonstr = string.Empty;
        object o; 
        try
        {
            cmd.CommandText = "usp_JsonPract";
            SqlDataAdapter adp = new SqlDataAdapter(cmd);
            adp.Fill(ds);
            var d =  ds.Tables[0].Rows[0][0];
            jsonstr = d.ToString();
            object a = JsonConvert.DeserializeObject(jsonstr);
            return (object)a;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }

异常如下:

“未终止的字符串。预期的分隔符:”。路径 'userDetails[2].data[1].addOns[1].name',第 59 行,位置 3。"

结果示例 JSON 是这样的:

{
"title": "Rice",
"data": [
    {
        "dishId": 11,
        "dishName": "stream rice",
        "dishPrice": 40.0,
        "dishImage": "streamrice.jpg",
        "dishType": "VEG",
        "dishPriceAndSize": [
            {
                "size": "Half",
                "price": 90
            },
            {
                "size": "Full",
                "price": 180
            }
        ],
        "addOns": [
            {
                "name": "Extrachess",
                "price": 25
            },
            {
                "name": "Chess",
                "price": 20
            }
        ],
        "includedEggs": false,
        "dishDescription": "stream rice is delicious in test",
        "rating": 4.5,
        "review": "GOOD",
        "discount": 20
    },
    {
        "dishId": 12,
        "dishName": "stream rice",
        "dishPrice": 40.0,
        "dishImage": "streamrice.jpg",
        "dishType": "VEG",
        "dishPriceAndSize": [
            {
                "size": "Half",
                "price": 90
            },
            {
                "size": "Full",
                "price": 180
            }
        ],
        "addOns": [
            {
                "name": "Extrachess",
                "price": 25
            },
            {
                "name": "Chess",
                "price": 20
            }
        ],
        "includedEggs": false,
        "dishDescription": "stream rice is delicious in test",
        "rating": 4.5,
        "review": "GOOD",
        "discount": 20
    },
    {
        "dishId": 13,
        "dishName": "stream rice",
        "dishPrice": 40.0,
        "dishImage": "streamrice.jpg",
        "dishType": "VEG",
        "dishPriceAndSize": [
            {
                "size": "Half",
                "price": 90
            },
            {
                "size": "Full",
                "price": 180
            }
        ],
        "addOns": [
            {
                "name": "Extrachess",
                "price": 25
            },
            {
                "name": "Chess",
                "price": 20
            }
        ],
        "includedEggs": false,
        "dishDescription": "stream rice is delicious in test",
        "rating": 4.5,
        "review": "GOOD",
        "discount": 20
    },
    {
        "dishId": 7,
        "dishName": "Chicken Biryani",
        "dishPrice": 160.0,
        "dishImage": "ChickenBiryani.jpg",
        "dishType": "NonVEG",
        "dishPriceAndSize": [
            {
                "size": "Half",
                "price": 90
            },
            {
                "size": "Full",
                "price": 180
            }
        ],
        "addOns": [
            {
                "name": "Extrachess",
                "price": 25
            },
            {
                "name": "Chess",
                "price": 20
            }
        ],
        "includedEggs": false,
        "dishDescription": "Special Chicken Biryani For Our Valued Guest",
        "rating": 4.5,
        "review": "GOOD",
        "discount": 20
    }
]}

如果有任何其他建议来实现这一点。请建议。

【问题讨论】:

  • 生成的 JSON 长度是否超过 2033 个字符?
  • 什么是异常message?您只发布了堆栈跟踪。
  • 好吧,对于初学者,您可以避免使用 ExecuteScalar。如果您阅读SqlCommand.ExecuteScalar Method,您会注意到它说:结果集中第一行的第一列,如果结果集为空,则为空引用(Visual Basic 中为Nothing)。 最多返回 2033 个字符。
  • FOR JSON 存在拆分大结果的问题。将整个内容包装在 SELECT (SELECT ... FOR JSON ...) 中而且你没有给 Newtonsoft 一个类型来反序列化,所以你只会得到一个 JObject
  • @AbuzarAnsari 如果你想获得帮助,你必须用文本替换图像。

标签: c# json sql-server asp.net-mvc asp.net-web-api


【解决方案1】:

创建一个名为 JsonPract.cs 的文件并粘贴以下类,以便创建几个可以映射到您在问题中发布的 json 的类:

public class JsonPract
{
    public string title { get; set; }
    public List<Datum> data { get; set; }
}

public class DishPriceAndSize
{
    public string size { get; set; }
    public int price { get; set; }
}

public class AddOn
{
    public string name { get; set; }
    public int price { get; set; }
}

public class Datum
{
    public int dishId { get; set; }
    public string dishName { get; set; }
    public double dishPrice { get; set; }
    public string dishImage { get; set; }
    public string dishType { get; set; }
    public List<DishPriceAndSize> dishPriceAndSize { get; set; }
    public List<AddOn> addOns { get; set; }
    public bool includedEggs { get; set; }
    public string dishDescription { get; set; }
    public double rating { get; set; }
    public string review { get; set; }
    public int discount { get; set; }
}

然后你可以将你的对象反序列化为:

JsonPract myDeserializedClass = JsonConvert.DeserializeObject<JsonPract>(myJsonResponse); 

例如:

public JsonPract SQLJSONPract()
    {
        string jsonstr = string.Empty;
        object o; 
        try
        {
            cmd.CommandText = "usp_JsonPract";
            SqlDataAdapter adp = new SqlDataAdapter(cmd);
            adp.Fill(ds);
            var d =  ds.Tables[0].Rows[0][0];
            jsonstr = d.ToString();
            JsonPract a = JsonConvert.DeserializeObject<JsonPract>(jsonstr);
            return a;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

【讨论】:

  • 感谢上面的代码适用于小型 json,现在我明白问题出在 SQL 端。你能通过我的SQL代码吗?当我返回大号时。来自 SP 的 JSON fromat 中的行数,然后得到此异常 "Additional text encountered after finished reading JSON content: ,. Path '', line 13, position 169."
  • @AbuzarAnsari 如果数据很好,那么 JSON 太长了。您应该考虑修改查询的结构或使用 EntityFramework 进行一些查询,然后在 C# 层而不是数据库层将其转换为 json。您的方法适用于中等规模。我认为您应该打开另一个与 SQL 相关的问题(粘贴映射、您的表、您的查询等),因为您在这里所做的主要问题与答案很好:How to parse SQL JSON string in C# in asp.net mvc 网络接口。它会得到比 C# 更深入了解 SQL 的人的关注
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 2014-12-20
  • 2011-10-27
  • 2017-11-20
相关资源
最近更新 更多