Recently I received a number of questions from people who were using the first self-monetization example code I created about a year ago. They received an error message when installing the app: Callback functions are not allowed.
This error happened because there is code in the install codeunit to do an outgoing HTTP call to a webservice. In the same period, people started to report that the sandbox environment showed a popup when they triggered an outgoing HTTP call from code.
Let’s first look at the reason why this popup happens and why there is an error message during installation. Microsoft introduced the possibility to create an online sandbox that contains a copy of the production data. To read more about that feature, refer to the documentation about the Business Central Administration Center.
Because the sandbox can now contain production data, including all settings, there must be a way to prevent unintentional outgoing webservice calls. As you can imagine, it could potentially lead to all kind of problems if a test environment is going to to webservice calls as if it is coming from a production environment. So for that reason, the sandbox blocks outgoing HTTP calls by default. This is also mentioned in the documentation of the Business Central Administration Center. And because the docker sandbox containers behave as if they are an online sandbox, you also get the same experience with blocking HTTP calls.
So that’s where the popup is coming from. The user can now select what to do. Is it safe to do the outgoing HTTP call or should the app be blocked? For always or only once? Please note that the setting you choose here applies the all HTTP calls from that app. So be careful with what you choose. And a special recommendation to tell your customers about this!
But what about the error message when you install an extension? Well, that’s easy: the platform recognizes an outgoing HTTP call and wants to present the popup to the user. However, if you install an app from VS Code or with PowerShell, then you don’t have a GUI. So the platform can’t show any popup. That’s where the error message comes from: ‘callback functions are not allowed’. This is the same error message as documented here. I have suggested on GitHub to just block the call in these cases.
There is a new table called “NAV App Settings” which has a field “Allow HttpClient Requests”. When the user selects one of the Always options (Allow Always or Block Always) then a record is inserted into this table with the field set to true or false.
You can also manage this setting from the Extensions Management Page.
This opens the configuration page where you can change the setting for the app.
What happens when an outgoing HTTP call is detected? Then the platform checks the table “NAV App Settings” if there is a record for this app. In case there is a record, then platform will either block or allow the HTTP call, based on the setting. When there is no record in this table, then the popup will be displayed to the user. Or the error message during install…
It is possible to create that record from code and with that prevent the popup from being displayed. Here is a code example how to do that.
As you can see, the code first detects if it is running in a sandbox environment and only runs in that particular case.
This code was inspired by a suggestion that was done in this issue on GitHub. It could be that Microsoft blocks access to this table in the future. Anyway, be very careful with this code! You should only do this when you are absolutely sure that this is safe to do. For example, in the new demo for self-monetization, I have piece of code as shown below. In this case, you can be sure that a call from the sandbox will end up in the test environment of the webservice. Other webservices might use different URL’s for test and production API’s.
Currently there is a bug when cleaning up the data. If you completely uninstall an app, including data, (e.g. with Sync-NAVApp -Mode Clean) then the record still remains in the NAV App Setting table. Also, the Recreate option for schemaUpdateMode in the launch.json does not clean that record. If you are testing your code you should be aware of this. The issue has been reported on Github.