Dynamics 365: Working with the virtual entities

By | October 30, 2017

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:

image

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:

image

So, make sure to configure the external names, and you should be able to see this:

image

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):

image

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:

image

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:

image

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:

image

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:

image

Surprisingly, there is only 1 record in the report as well:

image

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.

One thought on “Dynamics 365: Working with the virtual entities

  1. Mikkel Pedersen Kaas

    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?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *