|
![]() |
#1 |
Боец
|
Давайте разбираться.
Цитата:
Тут не вручную, а помощью стандартного класса FormJsonSerializer (D365). Во-вторых - задача, когда на вход извне впаривают сырой JSON (или XML) стоит сплошь и рядом: "Мы вам будем передавать XML\JSON строку и точка. Мы не можем переделать нашу систему под вашу, чтобы завязаться на ваш веб сервис. Или можем, но за большие деньги, где-то через года пол. Наши клиенты по всему миру, мы работаем только так". А какие есть альтернативы? Чаще всего для jSON встречается ручной парсинг строк strScan, strFind и т.д. Изредка попадаются продвинутые выринты - используют Newton.JSon.dll. C XML немного проще - стандартный класс пробега по XML с большего освоили, но это всё-равно абсолютный хардкод. Про аттрибут: Класс FormJsonSerializer понимает только DataCollectionAttribute. Более того, для дата-контрактов с их parm* методами этот аттрибут идеально подходит (на входе один параметр с таким же типом что и на выходе). AifCollectionTypeAttribute пришел из AX2012. Он больше подходит для описания сервис-операций, где может быть несколько входных параметров, разных типов, а на выходе что-то третье. Но в AX2012 других выриантов не было. Для сравнения: X++: // D365: [ DataMemberAttribute("Student list"), DataCollectionAttribute(Types::Class, classStr(StudentInfoContract)) ] public List parmStudentList(List _studentList = studentList) // ИЛИ AX2012: [ DataMemberAttribute("Student list"), AifCollectionTypeAttribute("return", Types::Class, classStr(StudentInfoContract)), AifCollectionTypeAttribute("_studentList", Types::Class, classStr(StudentInfoContract)) ] public List parmStudentList(List _studentList = studentList) Единственное - не уверен, понимает ли сериализатор D365 этот атрибут при описании контрактов для веб-сервисов - не приходилось применять, но как бы must Have. В XML так нельзя. В jSON можно. Претензия к автору блога у меня только одна: корее всего куски кода он где-то вырвал и не тестировал. Или спешил, промазал и недопроверил X++: while (enumerator.moveNext()) { Newtonsoft.Json.Linq.JObject jObj = enumerator.current(); studentInfoContract = FormJsonSerializer::deserializeObject(classNum(StudentInfoContract),jObj.ToString()); str studentId, studentName; studentId = studentInfoContract.parmStudentId(); studentName = studentInfoContract.parmStudentName(); Info(strFmt("Studnet # %1: %2", studentId, studentName)); } X++: Newtonsoft.Json.Linq.JObject jObj = enumerator.current(); Наверное он так хотел сделать: X++: public static void main(Args _args) { StudentsContract studentsContract; void addStudent(str _id, str _name) { StudentInfoContract student = new StudentInfoContract(); student.parmStudentId(_id); student.parmStudentName(_name); studentsContract.parmStudentList().addEnd(student); } studentsContract = new StudentsContract(); studentsContract.parmStudentList(new List(Types::Class)); addStudent("1", "First"); addStudent("2", "Second"); // Serialize str jSon = FormJsonSerializer::serializeClass(studentsContract); // Deserialize studentsContract = FormJsonSerializer::deserializeObject(classNum(StudentsContract), jSon); ListEnumerator enumerator = studentsContract.parmStudentList().getEnumerator(); while (enumerator.moveNext()) { StudentInfoContract student = enumerator.current(); info(strFmt("Studnet # %1: %2", student.parmStudentId(), student.parmStudentName())); } } Последний раз редактировалось DSPIC; 29.12.2021 в 15:25. |
|
|
За это сообщение автора поблагодарили: sukhanchik (4), vmoskalenko (6). |
![]() |
#2 |
Участник
|
Имя стандартного класса как бы намекает, что он задумывался больше для форм, чем для сервисов
![]() Цитата:
Цитата:
![]() ![]() Цитата:
X++: [DataMemberAttribute] public str parmDataSourceRecordsPacked(str _dataSourceRecordsPacked = '') { if (prmIsDefault(_dataSourceRecordsPacked)) { return SysOperationHelper::base64Encode(this.parmDataSourceRecordMapPacked()); } return SysOperationHelper::base64Encode(this.parmDataSourceRecordMapPacked(SysOperationHelper::base64Decode(_dataSourceRecordsPacked))); } ![]() Во-вторых, никто не мешал даже в AX2012 определить свой класс атрибута и парсить вручную что угодно аналогично тому, как это теперь делает FormJsonSerializer. Цитата:
Сообщение от DSPIC
![]() Для сравнения:
X++: // D365: [ DataMemberAttribute("Student list"), DataCollectionAttribute(Types::Class, classStr(StudentInfoContract)) ] public List parmStudentList(List _studentList = studentList) // ИЛИ AX2012: [ DataMemberAttribute("Student list"), AifCollectionTypeAttribute("return", Types::Class, classStr(StudentInfoContract)), AifCollectionTypeAttribute("_studentList", Types::Class, classStr(StudentInfoContract)) ] public List parmStudentList(List _studentList = studentList) PHP код:
А для AifCollectionType мы получили StudentListAif в виде ArrayOfStudentInfoContract с полной разблюдовкой: мы видим в WSDL и сам StudentInfoContract, и то, что он состоит из двух строковых полей: StudentId и StudentName. И повторюсь: для AifCollectionType платформа занимается тем, что десериализует для вашего сервиса коллекцию объектов и заодно проверяет, что объекты в коллекции - нужного типа, а не абы что. По-моему, это всё в совокупности стоит того, чтобы добавить методу лишний атрибут. Последний раз редактировалось gl00mie; 29.12.2021 в 23:28. |
|
Теги |
d365fo, json, интеграция |
|
|