C# 如何在Json中反序列化Json?

C# 如何在Json中反序列化Json?,c#,json,json.net,C#,Json,Json.net,以下是php web应用程序返回的json: {"subtotal":475,"tax":47.5,"discount_section":[{"amount":237.5,"name":"test prior for percentage discount "}],"grand_total_incl_tax":332.5} 我使用c#和json.net来解码abvoe json var cart = webClient.DownloadString("http://localhost/m1/p

以下是php web应用程序返回的json:

{"subtotal":475,"tax":47.5,"discount_section":[{"amount":237.5,"name":"test prior for percentage discount
"}],"grand_total_incl_tax":332.5}
我使用c#和json.net来解码abvoe json

var cart = webClient.DownloadString("http://localhost/m1/pos_addToCart.php?pidstr=" + pid_str);

dynamic result = JObject.Parse(cart);
但这一行有一个错误:

order_discount_section.Text = result.discount_section;
错误:

Cannot implicitly convert type 'Newtonsoft.Json.Linq.JToken' to 'string' 
如何将此json转换为字符串:

Key1 = Value1
Key2 = Value2
Key3 = Value3

根据您提供的json,折扣部分是一个映射,因此它不能表示为字符串。这就像试图将字典转换为
字符串
,或将
数组
转换为
字符串

如果希望将其作为
字符串
表示,那么在
结果.discount\u部分
之后添加
ToString()
(即
结果.discount\u部分.ToString()
)应该可以实现这一点

尽管我建议您通过占位符值存储数据,例如:

string name=result.discount\u段[0]。name
(与金额相同,但浮动/十进制/双精度…)

或者如果你想把它作为文本,就把它作为

text = "Name: " + result.discount_section[0].name 
       + "Amount: " + result.discount_section[0].amount.ToString();`
显然,使用stringbuilder或其他工具会更好(例如
string.format
),但我将把它作为“练习”留给您

编辑: for循环用于所有结果

totalText = ""
for (i = 0; i < result.discount_section.length; i++) {
    totalText += "Name: " + result.discount_section[i].name + "Amount: " + result.discount_section[i].amount.ToString() + "\n";
}
totalText=“”
对于(i=0;i

显然,如果您想要一个字符串数组,那么您只需构建一个数组,然后还可以使用i作为字符串数组索引。

Json.NET
提供了正确的行为

从您的示例字符串中可以看出,
discount\u section
是一个json数组,或者
JArray
,是解析到
JObject
JToken
的后代

如果要访问此数组的内部成员,例如
name
,则应将其称为

order_discount_section.Text = result.discount_section[0].name;
如果要按原样编写
折扣部分的完整符号
,应显式调用
ToString
方法:

order_discount_section.Text = result.discount_section.ToString();

尽管如此,当您在
JSON
中处理单独的服务响应时,处理
dynamic
s是没有用的。最好是定义一个单独的类,它将处理JSON值,这样您不仅可以看到JSON正在传递什么,而且可以与它一起工作

您可以考虑使用对象和使用反序列化。例如:

class Discount
{
    public Decimal Amount { get; set; }
    public String Name { get; set; }
}

class Response
{
   public Decimal Subtotal { get; set; }
   public Decimal Tax { get; set; }
   public List<Discount> Discount_section { get; set; }
   public Grand_total_incl_tax { get; set; } 
}

var response = JsonConvert.DeserializeObject<Response>(cart);
类折扣
{
公共十进制数{get;set;}
公共字符串名称{get;set;}
}
班级反应
{
公共十进制小计{get;set;}
公共十进制税{get;set;}
公共列表折扣_部分{get;set;}
公共总计(含税){get;set;}
}
var response=JsonConvert.DeserializeObject(购物车);
当对象结构相对固定时,此方法很好,并具有以下优点:

  • 结构清晰
  • 类型不匹配时的相关错误(JSON->property)

结果。折扣部分是集合。不能直接设置为字符串变量

试试这个

        var result= JObject.Parse(cart);
        dynamic[] discountSection = result["discount_section"].ToArray<dynamic>();
        decimal amount = discountSection[0].amount;
        decimal name = discountSection[0].name;
var result=JObject.Parse(购物车);
动态[]折扣部分=结果[“折扣部分”]。ToArray();
小数金额=折扣部分[0]。金额;
十进制名称=折扣节[0]。名称;
用于词典

Dictionary<string,decimal> discountDictionary =  discountSection.ToDictionary<dynamic, string, decimal>((d) => d.name, (d) => d.amount);
Dictionary折扣Dictionary=discountSection.ToDictionary((d)=>d.name,(d)=>d.amount);

折扣\u节是一个数组。尝试结果。折扣\u节[0]。名称尝试将结果强制转换为动态。根据上面的例子,我认为应该是这样的。我对你的答案投了赞成票,因为它的内容很丰富。但是我建议你格式化你的答案,因为很难阅读。当然:)我刚刚有一部手机,无法正确地进行格式化。我会把它格式化得更好一点,也感谢Thili77的编辑。如果result.discount\u部分有两个以上的数组?我该如何循环呢?那就放一个for循环。我会在我的回答中加上这个。