C#假如解析一个不知道类型的json对象

.Net技术 码拜 9年前 (2016-03-11) 2458次浏览
现在要对接PHP提供的json字符串
包含信息 { 创建人,.. 单据对象{单据头,[{单据明细…}] …}}

{"Creator":"dss","NeedUpDateFields":[""],"Model":{"FID":0,"FBillTypeID":{"FNumber":"XSDD01_SYS"},"FBillNo":"1535759143","FDate":"2015-12-24","FBusinessType":"NORMAL","FSaleOrgId":{"FNUMBER":101},"FCustId":{"FNUMBER":"CUST0001"},"FReceiveId":{"FNUMBER":"2014082202"},"FSettleCurrId":{"FNumber":"PRE001"},"FHeadDeliveryWay":{"FNumber":"JHFS01_SYS"},"FSalerId":{"FNumber":"040101"},"FSaleOrderEntry":[{"FSeq":1,"FSettleOrgIds":{"FNumber":101},"FUnitID":{"FNumber":"Pcs"},"FMaterialId":{"FNumber":"2040020044"},"FQty":"15","FDeliveryDate":"2016-05-20","FOrderEntryPlan":[{"FEntryID":0,"FPlanDeliveryDate":"2016-05-20"}]}],"FSaleOrderFinance":{"FDetailID":0,"FExchangeRate":1}}}

本人知道在C#与C#对接时,是可以按指定类型转换成功。
但是未知类型的json对象,即使本人把这个复杂的对象按 类型全部列出来,都不能正常转换,只能获取到第一层级 创建人 这一行,单据对象、单据明细都为null

解决方案

10

可以使用Newtonsoft.Json
首先根据JSON格式构造相应的数据结构,使用JsonProperty可以显式指定属性对应JSON的key,例如:
[JsonProperty(“alarm_id”)]
public string No
{
get { return _no; }
set { _no = value; NotifyOfPropertyChange(( ) => No); }
}
就是将JSON中alarm_id的值转换成 No
最后,获取到JSON,使用JsonConvert.DeserializeObject<T>(json)完成数据转换

30

可以用Json.net。
JsonConvert可以不用知道对象类型。
你可以把它当成一个JObject,也可以把它当成一个dynamic。

string json = "{"Creator":"dss","NeedUpDateFields":[""],"Model":{"FID":0,"FBillTypeID":{"FNumber":"XSDD01_SYS"},"FBillNo":"1535759143","FDate":"2015-12-24","FBusinessType":"NORMAL","FSaleOrgId":{"FNUMBER":101},"FCustId":{"FNUMBER":"CUST0001"},"FReceiveId":{"FNUMBER":"2014082202"},"FSettleCurrId":{"FNumber":"PRE001"},"FHeadDeliveryWay":{"FNumber":"JHFS01_SYS"},"FSalerId":{"FNumber":"040101"},"FSaleOrderEntry":[{"FSeq":1,"FSettleOrgIds":{"FNumber":101},"FUnitID":{"FNumber":"Pcs"},"FMaterialId":{"FNumber":"2040020044"},"FQty":"15","FDeliveryDate":"2016-05-20","FOrderEntryPlan":[{"FEntryID":0,"FPlanDeliveryDate":"2016-05-20"}]}],"FSaleOrderFinance":{"FDetailID":0,"FExchangeRate":1}}}".Replace("\"", """);
JObject obj = JsonConvert.DeserializeObject(json) as JObject;
int qty = (int)obj["Model"]["FSaleOrderEntry"][0]["FQty"]; // 15
// dynamic的做法:
dynamic d = obj;
int q = d.Model.FSaleOrderEntry[0].FQty; // 15

10

一个简单的例子:
class TestStudent
{
[JsonProperty(“sname”)]
public string Name
{
get;
set;
}
[JsonProperty(“iage”)]
public int Age
{
get;
set;
}
}
class TestClass
{
[JsonProperty(“sname”)]
public string ClassName
{
get;
set;
}
[JsonProperty(“lsstudents”)]
public List<TestStudent> Students
{
get;
set;
}
}
测试:
TestClass tt = new TestClass( );
tt.ClassName = “一年级”;
tt.Students = new List<TestStudent>( );
tt.Students.Add(new TestStudent( ) { Name = “王二” , Age = 12 });
tt.Students.Add(new TestStudent( ) { Name = “张三” , Age = 13 });
var jsonstr = JsonConvert.SerializeObject(tt).ToString( );
var classobj = JsonConvert.DeserializeObject<TestClass>(jsonstr);
其中,jsonstr的值应该是:{“sname”:”一年级”,”lsstudents”:[{“sname”:”王二”,”iage”:12},{“sname”:”张三”,”iage”:13}]}

20

引用 4 楼 l1314j 的回复:


假如本人需要再编辑这一个对象呢。
例如再删除一行订单明细,然后再增加一行明细
假如不用知道这个对象,那增加一行不是很麻烦了

需要“编辑”,说明你需要一定的业务逻辑。
这种情况下,你最好使用强类型的方法(类型你不妨本人定义)。
JOjbect等本身倒是可以编辑。但是,利用探索和猜测去进行编辑,总是不如使用安全的强类型。

20

引用 4 楼 l1314j 的回复:
Quote: 引用 2 楼 Forty2 的回复:

可以用Json.net。
JsonConvert可以不用知道对象类型。
你可以把它当成一个JObject,也可以把它当成一个dynamic。

string json = "{"Creator":"dss","NeedUpDateFields":[""],"Model":{"FID":0,"FBillTypeID":{"FNumber":"XSDD01_SYS"},"FBillNo":"1535759143","FDate":"2015-12-24","FBusinessType":"NORMAL","FSaleOrgId":{"FNUMBER":101},"FCustId":{"FNUMBER":"CUST0001"},"FReceiveId":{"FNUMBER":"2014082202"},"FSettleCurrId":{"FNumber":"PRE001"},"FHeadDeliveryWay":{"FNumber":"JHFS01_SYS"},"FSalerId":{"FNumber":"040101"},"FSaleOrderEntry":[{"FSeq":1,"FSettleOrgIds":{"FNumber":101},"FUnitID":{"FNumber":"Pcs"},"FMaterialId":{"FNumber":"2040020044"},"FQty":"15","FDeliveryDate":"2016-05-20","FOrderEntryPlan":[{"FEntryID":0,"FPlanDeliveryDate":"2016-05-20"}]}],"FSaleOrderFinance":{"FDetailID":0,"FExchangeRate":1}}}".Replace("\"", """);
JObject obj = JsonConvert.DeserializeObject(json) as JObject;
int qty = (int)obj["Model"]["FSaleOrderEntry"][0]["FQty"]; // 15
// dynamic的做法:
dynamic d = obj;
int q = d.Model.FSaleOrderEntry[0].FQty; // 15

假如本人需要再编辑这一个对象呢。
例如再删除一行订单明细,然后再增加一行明细
假如不用知道这个对象,那增加一行不是很麻烦了

JSON应该是进行数据传递用的,最终你的业务应该是基于实体类的。
你所需要的,是实体类的实现,以及实体类对象和JSON字符串之间的互相转换

10

是的,既然你不知道你得到的 json 是什么类型的,那么也就不会知道他其中每个字段的含义
自然也就不能对其增删查改了
所谓 不用知道对象类型 只是试图用程序对未知对象进行解析的尝试而已
也就是说,你可能收到好几种 json,但提供者有没有告知你具体是哪一种
于是你只能先行探测一下,然后再根据判定的类型进行解码

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C#假如解析一个不知道类型的json对象
喜欢 (0)
[1034331897@qq.com]
分享 (0)