AfterProperties of an event receiver, whether an old-school server-side Receiver or a RemoteEventReceiver, will always only contain the values that were submitted to SharePoint. In the case of an update made via code through one of the APIs, this is usually just the small number of fields that are being changed, most of the other values do not get Posted or submitted to SharePoint. In those cases, you can be guaranteed to only have the changed values in the
Classic-mode SharePoint sites use ASP.NET WebForms and a "traditional" postback when the user clicks the "Save" button. This means that even if the user didn't modify a single value on the Form, if they hit "Save", every field visible on the form gets Posted back to the server and will all appear in the
AfterProperties, even if they are identical to the previously saved values on the Item.
Modern-mode sites fall somewhere in the middle -- and if you build a PowerApp replacement, depending on how you configure it, it will behave slightly differently. The modern item form only makes fields editable when a user clicks on them, and depending on the type of item, it may even auto-save each changed value as the user moves from field to field, saving each one independently.
Even before the introduction of modern list forms, a well designed Event Receiver needed to build code to accommodate the possibilities that values may or may not be in the
AfterProperties. Having a mixture of classic and modern sites may make the problem more pronounced, but it is technically not a "new" problem. Regardless of what type of site you are responding to, use these guiding principals to ensure that your EventReceiver will work in all scenarios:
- If you are building code that needs to check if a certain field or fields were changed, first check if it even exists in the
AfterProperties, because if not, then you know it didn't change. If it does exist, you still need to compare that value to the same in the
BeforeProperties to see whether it actually changed or was just a identical value re-posted.
- If you are building code that needs to do something with a specific field regardless of whether it was changed, then just forget about
AfterProperties and always grab a reference to the actual ListItem. If you are doing a synchronous EventReceiver where the ListItem hasn't been updated yet, you can always check for existence of the field value in
AfterProperties first, and if it is not present, then grab the ListItem.