It seems the basics of the Virtual Entities have been covered in the blog post below while this feature was still in the preview:
https://blogs.technet.microsoft.com/lystavlen/2017/09/08/virtual-entities/
Now that we do have it in V9, it seems that one major issue that will be limiting our ability to use Virtual Entities in the real-life scenario is security because Virtual Entities are organization-owned, so they cannot be really controlled by the Dynamics security.
Every CRM user will either be able to see all or nothing – from the integration perspective, that’s almost never going to work.
I wanted to explore, then, if there is an option to limit access to the virtual entities with the help of the RetrieveMultiple plugins, and that’s what this post is going to be about.
To start with, let’s create a virtual entity as described in the post above.. while doing this, keep in mind that, once you have the data source and the virtual entity, you still need to map the fields. If you don’t do that, you’ll get the following error message:
Entity could not be retrieved from data source. Please try again or contact your system administrator
If you see that error message, make sure you did configure field mappings:
So, make sure to configure the external names, and you should be able to see this:
If you look at the security role configuration, the only 3 permissions you’ll be able to give on that new entity are Read/Append/AppendTo (all on the organization level):
So, yes, we are allowed to set up relationships between virtual entities and other entities.. Although, when setting up a 1:N between a native entity and a virtual entity, we have to provide an external name for the lookup field:
Which makes sense since there has to be a lookup on the “N” side of the relationship.
Either way, at this point there is a Virtual Entity but there is, basically, no security. By the way, we are, actually, allowed to build SSRS reports for the virtual entities:
So that turns the original question of whether we can use a plugin to introduce some security into a somewhat more complicated one.. Since RetrieveMultiple plugins do not work for SSRS reports, even if we can make that plugin work for the Virtual Entity, can we also make it work for the SSRS reports?
In theory, if we can use a plugin, then we can, probably, comes up with a custom security model. But developing a complete solution is not the purpose of this post – really all I wanted to do is to see whether I can use a plugin to start with. Let’s see then..
Here is my plugin code:
using System; using System.Activities; using System.Collections; using System.Xml.Linq; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System.Collections.Generic; using System.Data; using System.Linq; namespace VETest { public class RetrieveMultiple: IPlugin { public void Execute(IServiceProvider serviceProvider) { ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); if (context.OutputParameters.Contains("BusinessEntityCollection")) { var results = ((EntityCollection)context.OutputParameters["BusinessEntityCollection"]).Entities.ToList(); List updatedResultList = new List(); foreach (Entity entity in results) { if (entity.Contains("tcs_name") && (string)entity["tcs_name"] != "Early morning start, need coffee") { updatedResultList.Add(entity); } } context.OutputParameters["BusinessEntityCollection"] = new EntityCollection(updatedResultList); } } } }
The idea is that, in the post-operation RetrieveMultiple, the plugin will go over the list of records returned from the datasource and will remove some of them from the results. In this particular case, a record with that particular value in the “name” field will be removed.
So, I got the plugin compiled, and here is how the steps has been registered:
You can do all of the above using XrmToolBox, btw. Just use CodeNow plugin to compile the plugin, and, then, use Plugin Registration plugin in XrmToolBox to register the plugin (that’s a lot of plugins in one sentence..) I’m using tcs_name attribute in that code, though, and that’s something you may need to change first.
Turns out, the plugin works just fine. There is only 1 record in the results now:
Surprisingly, there is only 1 record in the report as well:
That last one makes it an interesting precedent, btw. I am wondering if all other SSRS reports will, eventually, go through the standard retrieve pipeline when querying data from Dynamics.. that would remove one of the important limitations we have now when using RetrieveMultiple for custom security.
Either way, it seems that it is possible to customize Virtual Entity security with the help of RetrieveMultiple plugins. Of course what I did above was a very simple example.. Nothing but a proof of concept, really. But it worked, and, it turned out, it also worked with SSRS, so, at the very least, we have a workaround – such a workaround will, likely, involve quite a bit of development, but that’s a different story.
When creating af lookup field from a virtual entity to a CRM entity, such as your example with a lookup to the Account entity, can only the primary ID field be used for this purpose – or is it possible to also use alternate keys? In most situations, I doubt the external data source will have the internal CRM ID.
Also, have you experienced with lookups between virtual entities?
Mikkel,
I am looking for the same info, did you found any answer about this?
I would be interested to know this as well. Can you link back to a data warehouse of some sort using an alternate key rather than the GUID?
Hi Alex. Useful article but I have a virtual entity that has been imported. There are no security options on the imported entity and I cant work out why they were lost on import. Any ideas?