As you know (I hope 😅), a few days ago we presented a session about Business Events for Developers at DynamicsCon. In this session, we were talking, among other things, about how we could customize the payload of the Business Events that we expose to the outside, to give them a different structure than the one that comes by default, and being able to reuse all the functionality that Dynamics F&O brings OOB.
At the end of the demo, we had a few minutes of live Q&A, and one of the assistants (J.C.) made a question related to the part of custom payloads: When downloading the scheme from the business events catalog, does it reflect the modifications introduced with this custom payload?. The answer, unfortunately, was no, but it seemed like a great idea that had not crossed my mind, apart from being really useful if you are going to consume the events for example in Power Automate, so I got down to work and this has been the result.
The first thing I did was check the possibility of extending the functionality of the “Download schema” button to try to modify its behavior, but it is not possible to go that way, so, finally, I decided to duplicate this button, and play with the visible property of both buttons, the standard and the duplicated, depending on the JATCustomEvent field that we added to the events catalog (BusinessEventsTable) to identify those events that will work with the custom payload.
Once the button is duplicated, we will control in the active method the visible property of the two buttons, the standard and the duplicate, basing its value on the JATCustomEvent field of the event catalog (BusinessEventsTable), which was created to identify those events that should use custom payload.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public int active() { int ret; ret = next active(); BusinessEventsTable businessEventsTable = this.cursor(); FormRun formRun = this.formRun(); FormCommandButtonControl downloadSchema = formRun.control(formRun.controlId(formControlStr(BusinessEventsWorkspaceCatalogPart, DownloadSchema))); FormCommandButtonControl jatDownloadSchema = formRun.control(formRun.controlId(formControlStr(BusinessEventsWorkspaceCatalogPart, JATDownloadSchema))); downloadSchema.visible(businessEventsTable.JATCustomEvent == NoYes::No); jatDownloadSchema.visible(businessEventsTable.JATCustomEvent == NoYes::Yes); return ret; } |
Finally, we add a new method to the extension of the BusinessEventsCatalogHelper class. This method will be a “duplicate” of the getJSONSchema method that generates this schema in a standard way, with the necessary modifications to respect our structure.
1 2 3 4 5 6 7 8 |
public static str jatGetJSONSchema(BusinessEventsContractEDT _businessEventsDataContract) { Object dataContract = new DictClass(className2Id(_businessEventsDataContract)).makeObject(); JATCustomDataContract customDC = JATCustomDataContract::construct(); customDC.parmData(dataContract); return FormJsonSerializer::serializeClass(customDC); } |
And this method will be executed from the new button that we have created, downloading the value returned by it in a text file, just as the standard does.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void clicked() { FormRun formRun = this.formRun(); FormDataSource formDataSource = formRun.dataSource(tableStr(BusinessEventsTable)); BusinessEventsTable businessEventTable = formDataSource.cursor(); next clicked(); if (businessEventTable) { str fileName = strFmt("BusinessEventSchema_%1.txt", businessEventTable.BusinessEventId); File::SendStringAsFileToUser(BusinessEventsCatalogHelper::jatGetJSONSchema(businessEventTable.Contract), fileName); } } |
And in this simple way we manage to add a little more functionality, adding great value to our development.
From here I want to thank the user J.C. (Sorry, but I don’t know your name 🤷♂️) for giving me the idea during the event to improve the product, and as always, the complete solution is available in the GitHub repository.
Greetings!
Followed this but I have run into an issue. I am unable to deserialize the Business event contract when it contains a list. Maybe you can assist me with this.
Hi Kenny, thanks for comment :).
Sure, you have to decorate the parm method that returns the list with the DataCollectionAttribute attribute, so you will let the deserializer know that this is a collection (list) and the type of the elements that contains.
Example, if you have a list of MyClass elements, you have to decorate it as following:
DataCollectionAttribute(Types::Class, classStr(MyClass))
Also, don’t forget the DataMemberAttribute attribute as well.
Hope it hepls you, best regards!