在.NET里Json的序列化和反序列化通常使用NewtonSoft这个类库,但是这个类库只能序列化反序列化.NET的实体。
在AX2012的时候,我的做法是在用.NET定义一系列实体,在AX2012里添加.NET的DLL,然后进行序列化和反序列化。
在D365里也可以继续这样做,并且都在VS里,引用.NET的类库更加直接很简单,可以直接在同一个solution里引用C#的Project。
不过总是感觉有些怪,所以除了不得不使用C#,比如需要用到某个.NET的类库涉及到泛型,这个X++不支持没办法调用,我通常还是喜欢尽量在X++的Project解决问题。
D365里新增了一个FormJsonSerializer类,用来做Json的序列化和反序列化,这个类也用到NewtonSoft的类库里的函数,这样封装以后达到的效果跟序列化.NET的实体一样简单。
Newtonsoft.Json.JsonConvert::SerializeObject Newtonsoft.Json.JsonConvert::DeserializeObject
上面是D365里使用.NET Entity调用NewtonSoft的方式。
FormJsonSerializer::serializeClass(entity); FormJsonSerializer::deserializeObject(classNum(Entity), entityStr)
上面是通过FormJsonSerializer封装以后使用X++的实体序列化和反序列化的代码,可以看出经过封装以后,调用跟使用.NET实体一样简洁了。
接下来就是X++中的实体怎么定义了。
1 [DataContract] 2 public class Entity extends FormDataContract 3 { 4 FormProperty Status; 5 FormProperty Message; 6 public void new () 7 { 8 super(); 9 Status = this.properties().addProperty(methodStr(Entity, parmStatus), Types::String, ""); 10 Message = this.properties().addProperty(methodStr(Entity, parmMsg), Types::String, ""); 11 } 12 13 [DataMember("<status>k__BackingField")] 14 public str parmStatus(str _status = Status.parmValue()) 15 { 16 if (!prmIsDefault(_status)) 17 { 18 Status.parmValue(_status); 19 } 20 return _status; 21 } 22 23 [DataMember("<msg>k__BackingField")] 24 public str parmMsg(str _msg = Message.parmValue()) 25 { 26 if (!prmIsDefault(_msg)) 27 { 28 Message.parmValue(_msg); 29 } 30 return _msg; 31 } 32 33 }
上面是定义X++ 实体的一个例子,比.NET里定义复杂一些。
1.类需要用属性DataContract标记
2.需要继承自FormDataContract
3.使用FormProperty定义实体属性
4.定义parm方法
5.new方法中将属性添加到Properties中,并将属性和parm方法关联。
总体比在.NET里定义实体只需要定义Property啰嗦一些,但是也还好不是太麻烦。