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

l1314j 2016-05-20 10:08:38
现在要对接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


...全文
1676 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
software_artisan 2016-05-20
  • 打赏
  • 举报
回复
我估计楼主没有把明细对象类型设置为对象集合。
xuzuning 2016-05-20
  • 打赏
  • 举报
回复
是的,既然你不知道你得到的 json 是什么类型的,那么也就不会知道他其中每个字段的含义 自然也就不能对其增删查改了 所谓 不用知道对象类型 只是试图用程序对未知对象进行解析的尝试而已 也就是说,你可能收到好几种 json,但提供者有没有告知你具体是哪一种 于是你只能先行探测一下,然后再根据判定的类型进行解码
songbing774933 2016-05-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




如果我需要再编辑这一个对象呢。
比如再删除一行订单明细,然后再增加一行明细
如果不用知道这个对象,那增加一行不是很麻烦了[/quote]

JSON应该是进行数据传递用的,最终你的业务应该是基于实体类的。
你所需要的,是实体类的实现,以及实体类对象和JSON字符串之间的互相转换
Forty2 2016-05-20
  • 打赏
  • 举报
回复
引用 4 楼 l1314j 的回复:
... 如果我需要再编辑这一个对象呢。 比如再删除一行订单明细,然后再增加一行明细 如果不用知道这个对象,那增加一行不是很麻烦了
需要“编辑”,说明你需要一定的业务逻辑。 这种情况下,你最好使用强类型的方法(类型你不妨自己定义)。 JOjbect等本身倒是可以编辑。但是,利用探索和猜测去进行编辑,总是不如使用安全的强类型。
l1314j 2016-05-20
  • 打赏
  • 举报
回复
引用 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
如果我需要再编辑这一个对象呢。 比如再删除一行订单明细,然后再增加一行明细 如果不用知道这个对象,那增加一行不是很麻烦了
songbing774933 2016-05-20
  • 打赏
  • 举报
回复
一个简单的例子:

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}]}
Forty2 2016-05-20
  • 打赏
  • 举报
回复
可以用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
songbing774933 2016-05-20
  • 打赏
  • 举报
回复
可以使用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)完成数据转换
adam_gin 2016-05-20
  • 打赏
  • 举报
回复
天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分 你还可以输入10000个字符 (Ctrl+Enter)
l1314j 2016-05-20
  • 打赏
  • 举报
回复
小结一下: 未知类型的json,但是格式统一 如果是需要编辑的json对象,转换成实体类型,使用强类型转换
 
JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Deserialize<T>(jsonText);
关键的问题,这个T太复杂,我是不想手写,后来才知道网上有现成的json转C#/Java实体类的方法,轻松简洁 http://www.bejson.com/convert/json2csharp/ 如果只是读取数据,使用楼上JObject和dynamic 两种类型,都是比较好的方法

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧