Implement all types of queries when filtering results using PreOperation RetrieveMultiple
Category: Design, Performance, Security, Supportability
Impact potential: Medium
RetrieveMultiple calls from different application display different results.
- For example: same views in legacy applications show different results in new applications.
RetrieveMultiple messages are typically the most commonly used messages. Plug-ins for these messages can significantly impact system performance. Generally, you should avoid using plug-ins for these messages if the requirements can be achieved some other way. More information: Limit the registration of plug-ins for Retrieve and RetrieveMultiple messages
Plug-ins registered on the
RetrieveMultiple message are typically intended to filter the results returned by queries for an entity. There are two strategies to do this using a plug-in registered on either the
This approach will potentially change the expected number of records returned in each page of results and can result in inconsistent experiences when the data is displayed in an application.
When using this approach you must implement the appropriate filtering for the different possible types of queries, most importantly: FetchExpression and QueryExpression. If you implement just one of these, different applications that use the other type of query will not apply your changes.
FetchXmlToQueryExpression messages provide the capability to convert one query type to another, because of the performance impact of including additional calls within
RetrieveMultiple, we recommend that you do not use these messages in this context. Rather, implement your filtering using the equivalent logic in both.
There is a third type of query that can also be used with
RetrieveMultiple: QueryByAttribute. This type of query does not provide for complex filtering and it isn't possible to include more complex filtering logic within a plug-in. Fortunately, this type of query is not frequently used. Depending on the sensitivity of the filtering you add, you may choose to reject queries of this type by throwing an InvalidPluginExecutionException.
See Sample: Modify query in PreOperation stage for an example of the strategy we recommend.
If a plug-in is written to change the records returned in a specific application which uses just one type of query used by that application, either FetchExpression or QueryExpression, the results may not be consistent in other applications or if the application changes the type of query used. Plug-ins should be written to provide the same result regardless of the application.
When using the Web API, GET requests on a collection are converted to QueryExpression unless the query uses FetchXml as described in Retrieve and execute predefined queries. In that case the queries use FetchExpression.
The legacy web client for model-driven apps is being replaced by Unified Interface. Unified Interface uses the FetchXml defined in the SavedQuery.FetchXml or UserQuery.FetchXml properties. For better performance, Unified Interface does not convert the FetchXml data to a QueryExpression before executing these queries as the legacy web client did. Therefore, queries that were modified in plug-in code for the legacy web client which used QueryExpression will not apply the same changes now that the query to support views is being passed using FetchExpression unless the plug-in code is written to apply same logic to FetchExpression queries.
Sample: Modify query in PreOperation stage
Query data using the Organization service
Use FetchXML to construct a query
Build queries with QueryExpression
Limit the registration of plug-ins for Retrieve and RetrieveMultiple messages
Unified Interface Community