When you create an instance in dataverse you get to choose which region it is located in. However, you do not get to choose which exact datacenter you get. How is this important? Well, if you want to mirror data using Azure Synapse Link or Microsoft Fabric, then these resources have to be in the exact same datacenter to work. If you have several instances, there is a risk that some are in one of the datacenters in the region and some in the other. For instance, in the region Europe, there are two datacenters, North Europe (Dublin) and West Europe (Amsterdam). So, it might very well be that some instances are in Dublin and some in Amsterdam.
Currently there is only one way to move an instance, and that is to create a ticket and ask Microsoft Support to do it for you. But you first need to know where it is.
The easiest way to find where you instance is located, is actually to start the wizard for synchronizing data to a datalake using Azure Synapse Link from the Maker-portal. It should look something like this:
However, if you have many instances, you might want to have a script that outputs this. Well, I did anyway, so I was looking into how to do this using Powershell.
Hence I dug into some of the PowerShell libraries for Power Platform and created this PowerShell script:
# Get all environments
$environments = Get-AdminPowerAppEnvironment
# Loop through each environment and output DisplayName and azureRegionHint to a file
$environments | ForEach-Object {
# Create a custom object with the properties you want
[PSCustomObject]@{
DisplayName = $_.DisplayName
Type = $_.EnvironmentType
azureRegionHint = $_.Internal.properties.azureRegionHint
}
} | Export-Csv -Path "C:\temp\output.csv" -NoTypeInformation
In this case the “azureRegionHint” was supposed to show the right datacenter. But that turned out to be a half-truth as many of the instances were correct but not all. I suspect it might be stored list and not the actual list, as at least one of the ones that were incorrect has been moved.
I reported this to Microsoft support, as my view is that the azureRegionHint should display the correct datacenter, and hence what I experienced is a bug. But I never got this acknowledged by support who instead recommended that I use “ping” to figure out the region;
C:\Users\GustafWesterlund>ping xxx.crm4.dynamics.com
Pinging db3--eurcrmlivesg000.crm4.dynamics.com [52.155.235.153] with 32 bytes of data:
Reply from 52.155.235.153: bytes=32 time=56ms TTL=107
Reply from 52.155.235.153: bytes=32 time=55ms TTL=107
Reply from 52.155.235.153: bytes=32 time=69ms TTL=107
Reply from 52.155.235.153: bytes=32 time=75ms TTL=107
Ping statistics for 52.155.235.153:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 55ms, Maximum = 75ms, Average = 63ms
In the response above, db is “Dublin” and my guess is that the “3” means datacenter 3 or something like that.
However, using ping to do what in essence is a nslookup didn’t seem very useful and I also wanted to be able to use PowerShell, so I looked up the command:
Resolve-DnsName -Name $url
This is in essence nslookup, which, if you are not very versed in this, will give you the IP address and official name of a specific alias (cname). As the following example shows:
PS C:\WINDOWS\system32> Resolve-DnsName -Name xxx.crm4.dynamics.com
Name Type TTL Section NameHost
---- ---- --- ------- --------
xxx.crm4.dynamics.com CNAME 300 Answer db3--eurcrmlivesg000.crm4.dynamics.com
Name : db3--eurcrmlivesg000.crm4.dynamics.com
QueryType : AAAA
TTL : 300
Section : Answer
IP6Address : 2603:1061:2002:968::36
Name : db3--eurcrmlivesg000.crm4.dynamics.com
QueryType : A
TTL : 300
Section : Answer
IP4Address : 52.155.235.153
The first part is the information that the DNS entry is a cname/alias to the aname which starts with db3. The following two blocks are the IPs in IP v6 and IP v4 of this name. Using this I adapted my script and added a manual switch which shows the datacenter which starts with “ams” as West Europe and “db3” as North Europe. Don’t know if this information is available anywhere so that I can look it up instead as that would be a lot more dynamic. But at least I can loop through all instances and get the azure datacenter for each of the instances. Here is the script:
I hope and guess there are easier ways to solve this. If you have any ideas, please let me know in the comments or if you have any other method to solve this for a lot of instances where using the UI would be a bit too much of a hassle.
Should a five user organization be entitled to the same amount of compute as a 5 000 user organization?
Entitlements are the limitations that Microsoft have set on the platform that are based on which type of license each user has. This is not the same as the API Service limits which are much more liberal. The entitlements have not yet been fully enforced as the reporting capabilities of the platform have not been rolled out fully yet. But they will. With this blog post I attempt to give my perspective on entitlements on the Power Platform and Dynamics 365 (CRM part).
My previous post was about API Service limits which are commonly referred to as the throttling limits of the platform. The entitlements limits (and here) have another part in the Microsoft docs that go into these a bit deeper. I’d first like to go into why there are two different “protections” or limitations.
The API Service limits are there to protect the platform from noisy neighbours. Some of us, that have been around since the earlier days of Dynamics 365/CRM online remember that the performance used to be rather shaky. This could often be due to the fact that some other instance on the same hardware your instance was hosted on, was being slammed with massive amounts of requests, like during a migration. To make sure that this “noisy neighbour” problem doesn’t occur, the API-limits have been put in place and since they have, things have been a lot better so they do seem to work.
The Entitlements are there for another reason. Let’s say you buy two (2) Dynamics 365 Sales users and then use integrations with a custom built front end for B2C purposes with one of those users (or an app user), and, still within the limits of the API Service limits, hammer the API:s from day to night with an amazing amount of requests. The B2C aspect would be covered from a licensing perspective in what was previously called “external connector” license and is nowdays included in the normal license. However, the amount of compute that the instance is utilizing is way above what you are paying for. This is the reason why Microsoft have created the entitlements, as far as I know anyway. And I think it only makes sense that there is some kind of reasonable proportionality to that.
To quote the Microsoft docs page: “These limits represent the number of requests users are entitled to make each day. The allocated limit depends on the type of license assigned to each user.“
What is a request? The first question is then, what is a request? Previously we were told, that a batch request (ExecuteMultiple) was one (1) request but that has since changed and is now considered to all the subparts. I would even think that a batch request has the extra overhead of the batch itself. Hence, a batch request with 10 creates, will actually be counted as 11 requests; 1 for the batch, and 10 for the creates. The exact definitions are not disclosed but we get a rather good description from the docs with this paragraph, where I have highlighted some interesting parts:
“For Dataverse, API requests include all data operations that interact with table rows where rows are created, retrieved, updated, or deleted (CRUD). Special operations such as share and assign are includedbecause they are considered updates. These requests can be from any client or application and using any endpoint. These include, but are not limited to, operations performed by plug-ins, async workflows, custom controls, and $batch (ExecuteMultiple) operations. There are a small set of system internal operations that are excluded, like login, sign out, and system metadata operations.”
The important takeaway here is hence that you cannot create a workaround by using a plugin and using the internal context pseudo-api to do the calls, as these are counted as well. Difference might be that they are done in the context of a specific user and that user has a rather large entitlement, which might hence “flatten the curve” so to speak. An interesting aspect, though is the exception to this rule:
“Power Platform API request allocations include use of Power Automate, AI Builder, and Connector APIs. All requests through a connector that result in a Dataverse request will represent 1 Power Platform request.”
This strongly indicates that Microsoft wants us to use the Power Platform tools and that these should not at least have additional costs. There are, however, still some inconsistencies in this area that I really hope that they fix, such as:
Microsoft supplied integrations in ADF
Integrations to Dynamics 365 Finance & Operations
Dynamics 365 Business Central
Exports to ADLS
Data Export Service
The latter two can be really heavy on the API:s if you have an enterprise system or a B2C system. I work with a customer which currently have a database of >400 GB which uses Data Export service and the amount of notifications on the Data Export Service just for Contacts for a year often exceed the hundreds of millions.
Other areas which are not mentioned but which I think are included are addon first-party apps like Customer Insight (Sales Insights) which actually uses a ADLS in the background (not that you can actually access it). I have heard stories of support tickets where Microsoft support have blamed the API Service protection for hitting the ceiling when it was Sales Insight that caused it, which would indicate that these are actually counted. I think the intention is to include all of these so that the license for these cover the API entitlements. I just wish they would fix the gaps as customers are being affected.
Entitlement telemetry might not be the same as API Service protection telemetry That actually brings up another interesting aspect. The measurements that are used for the API Service protections are probably NOT the same as the measurements that are used for entitlements, but this is based on my personal hunch, and not any kind of facts. Mainly based on the assumption that I think that the areas that are excluded from entitlement measures above, probably are not excluded from the API Service protection.
Another definition of request!? On this page there is another definition of what a request is that is different from the one above. I believe this is older than the one mentioned above, as it uses the term “CDS” which has been replaced by dataverse now. I am not sure though as this page last change is dated on the second of feb 2021 while the other the 5:th of March 2020. The main difference is that this does not make the exception mentioned in the article above, hence every call through a connector, every successful or failed call in Power Automate will be counted as one request. Hopefully Microsoft will clear this up soon.
Entitlements per user At this link you can find the specific entitlements per license. They are all measured on a 24 h period and range from 20 000 for the full enterprise versions of Dynamics 365 to Power Apps per app plan which get 1000 requests.
Entitlements for non-licensed users, which mainly will be application registrations/application users are fixed per tennant based on the highest licensed purchased on the tennant. This means the following pooled included non-licensed entitlements.
The important note here is that this does not scale at all, but is fixed. And if you plan to do some integrations with a Power Apps only tennant, you’d be wise to buy at least one Dynamics 365 Enterprise, just to get the non-licensed user entitlements, as the Sales Enterprise is around $95 and each additional 10 000 is $50, which means that the saving to get to a 100 000 calls / 24h is:
Buying extra capacity It is also possible to buy extra API capacity. You can read more about this in the Licensing Guide for the Power Platform. I am not able to find a current price for this at this time, but the list price was previously set at $50 (per 10 000 for 24h). These are then to be allocated to the users as you wish.
Overshooting “Users will not be blocked from using apps for occasional and reasonable overagesat this point of time.“ What will happen when or if you overshoot? A very important question. Most organizations will at some time do this, most probably during migration of data from the old systems. The statement from Microsoft above, especially the highlighted “at this point of time.” is rather omnious. It does indicate that at some time the hammer will come down. But at this time it won’t, admins will be harassed with emails about overshooting and just as with overshooting data capacity, they might start with blocking some features when you are overshooting. It is mentioned in one of the articles in the FAQ that after the transition period they will start blocking. So that will be a real fact unless they change their mind on that.
My very strong advice, is hence that all organizations that are not compliant need to start looking at this as soon as possible. I have some tips on what you can do further down in this article. Please refer to these and feel free to leave a comment if you have questions on the subject not answered here.
ISV Bundling There are many ISV:s which export rather large amounts of data. The first ones that come to mind are the Marketing Automation products like Adobe Marketing, Click Dimensions, Dot Digital and more. These all synchronize contacts, marketinglists and marketinglistmembers, at least, which for larger installations can be quite large datasets. I do think it would be advantageous if these ISV:s could include the API Entitlements that are required, or if they are billed by Microsoft to the ISV which in turn bills the customer with a surcharge. At the very least Microsoft have to take ISV:s into the equation here as they are an essential part of the ecosystem, especially from the customer perspective.
Tips on how to handle future entitlement enforcement
Start by using the PPAC to get an overview of how your situation looks even though you might not get an exact picture.
Consider the overhead of batching. There can be performance advantages to batching as mentioned in my previous article. But there needs to be
Consider “outsourcing large datasets” to ADLS – although the ADLS export also uses API-calls.
Maybe not a problem if short term – for now
Consider using official connectors or Power Automate instead (although that might cause costs in itself)
If building Power App licens based solutions and you have heavy integrations, buy one Dynamics 365 Enterprise license.
If possible impersonate the data load over all the users. This can be done with plugins and synchronous workflows for instance. Patterns that can be used in this case can be staging tables in dataverse where the owner is set and then a plugin is triggered that slices the row into many pieces as the owner of the import record. I am not sure if impersonation using the API will have any effect on this. That needs to be investigated. If it can be used to spread the load, that would be a good pattern to use.
Refactor inefficient code. Depending on implementation maybe increase use of caching or other techniques to reduce the amount of requests. Make sure you have skilled Power Platform/Dynamics 365 developers working with development as knowing how to do this very particular to this platform.
Microsoft representatives, locally in Sweden anyway, are saying to our customers and potential customers that they need not worry about this. I find that message a bit mixed with what I read here. On the other hand I think this will be a very rough change for many organizations. If your organization will be very negativly affected by this and you feel that you are still paying “fairly” for your part, then I suggest you contact Microsoft and describe your business scenario in detail. If you need help with who to contact you can always start with the people who have written the articles who you can ask to forward the articles to the right people, use your local user group or ask some local MVP for help as they often have contacts directly with the product group (and many other experts do too).
Good luck and do leave a comment or share this if you like it!
(Updated) Microsoft recently released some throttling that have been causing some stir in the community, especially since the latest throttle, the concurrency throttling, was not very openly announced, some partners and customers were hit rather hard by it as it affected their abilities to manage large dataloads in the system.
Now Microsoft have announce another API based limitation which is based on the users and the type of licenses the have. You can read some about it here if you like. This article will discuss what this means and my personal view of the good, the bad and the ugly of it.
First of all we need to understand what it is. It is a API limit that will be set per user and based on the type of license that the user is allocated. The highest is if you have a Dynamics 365 App user license, like Sales, Customer Service or similar, which will give you 20 000 requests per 24 hours. The lowest is a Power App – Per App license which will give you 1 000 requests per 24 hours. Note that these are connected to the user and not summed/aggregated to the instance level (allthough I would think that would be a good idea). Well, really, the lowest of them all are Application, Non-interactive or admin-users that don’t use a license as these will be allocated 0.
I have not seen any UI for this yet, so I don’t know how this will look, but what the page is saying is that API-calls can be reallocated from normal users to application users/non-interactive users. (UPDATE – See update at the bottom regarding this, thank you observant readers!) Not sure if it will also be possible to reallocate API-calls between normal user and another normal user.
There will also be an additional SKU for buying 10 000 additional API calls per day that can be allocated to a user.
The Good
What is good about this then you might ask? Well, I think it is fair. Large customers pay a lot of money for their instances and usually use it a lot with a lot of integrations. It is only fair that they are allowed to use the API:s more than a small customer who has created some super duper application that blasts Dynamics with massive amounts of calls. The small customer can still do this, but they just have to pay a bit extra for those API-calls if they arn’t covering that with their users. I also hope that this might enable Microsoft to relax the currently rather tight throttling on the API:s a bit.
According the the licensing documentation in general, existing customers will not be hit by this until October 2020, in other words, more than a year from now. This will hence probably only now affect new customers.
The bad
This implementation certainly has some bad parts. The most obvious is the too stringent connection to users which makes it weird. I don’t know how this will be managed in the UI but let’s say we have an instance with 500 users mixed Sales Enterprise, Customer Service Professional and Team Member. We also have 10 application users that are used for Portals, Forms Pro and custom integrations to many other systems. Each integration using a separate integration user to reduce the attack area in the unlikely event of a hacker attack. So what we will need to do is to first figure out how much API-usage we are using for all the normal users (for instance via PCF:s, Flows, Plugins, Workflows etc) and all the integration application users. Currently the https://admin.powerplatform.microsoft.com does not give us this granularity. There are indications but in this case one would need deep granualar data, preferably with trend analysis.
Another part of this that could be done better is the “buying addional API-calls”. Why not just adapt the method used in Azure? In other words, you pay as you go. With this current method, you have to know beforehand how much a particular user will use and if you overshoot the user will be shut down causing unnecessary support costs for customers, partners and Microsoft.
I also wonder how this practically is going to be handled? Are admins going to go into each of the 500 user records, reduce the API-calls allocated and move to Application users? If the admin moves all calls, which effectivly will stop plugins, workflows, javascripts with server calls etc how will the error handling of that look?
The Ugly
What is really the difference between something bad and something ugly? I would say that something bad is a design decision that we might dislike or might be disadvantage to the customers, it requires some sort of conscious perspective. Ugly on the other hand is the parts where where, in this case, Microsoft just have forgotten to think about something or neglected perspectives which causes issues for partners or customers. Based on this, I would say that the following are the bad aspects of this;
Timing
Again Microsoft are rolling out a change with a rather short timeframe. They probably feel that a month or two of notice by publishing the article above is notice enough, but they have to realize that many customers cannot act that fast. If you are a small customer with extensive use of Dynamics, for instance if you are using Dynamics 365 in a B2C aspect with a Marketing Automation integration and you are targeting millions of customers with sendouts and hits on your webpage being mirrored to your Dynamics all the time, this will cause some hefty API traffic. And your org might not be very big if you are totally e-commerce oriented.
Maybe only new customers, for now
Lastly I really hope that it is true that the API limitation will not affect current customers, it is not very clear and hence we are left in the dark again. If there is a problem with application users etc not being able to log in, I hope Microsoft support will be ready for the storm that will hit them.
On the other hand, new customers might have tested the system, evaluated the costs and are now faced with this. Not sure that will be optimal either, there is risk of loosing a customer or two there.
Communication
As this is a rather drastic change and may be viewed as a “breaking change” if not the one year grace period mentioned in the licensing in general applies to this. No matter, this should have been communicated very clearly months ahead to remove any kind of doubt from partners and customers. Both via blogs, emails to admins of organizations using Application users/non-interactive users as this should be easy to figure out via telemetry. Currently no one knows exactly when this will hit them/their customers or how they are to manage it.
This is generally very unclear. I shouldn’t have to write an article like this, speculating about what is or isn’t going to happen. If I have problems figuring this out, being an MVP, customers are probably very much in the dark, both existing and new.
Conclusion
In conclusion I think this is a good idea that got rushed. It should have been passed through a couple of more hoops before being launched to get the right feedback. The main things that I think Microsoft should change before rolling this out that, from my perspective, still give the same effect, are:
Aggregate all API-Calls that are counted to a per instance level. It will make it easier to manage, stop the breaking change and make it easier to understand.
Enable admins to add a per-use, after the fact, payment option, (like Azure) for any additional API-calls.
If this is going to be useful or not also is very dependent on the fact that we can reallocate a lot of the API-calls from users to the integration users. For instance, I have a B2C customer with 1M+ API calls per 24/h and if it will not be possible to take the sum of hundreds of users and allocate those to the application users we are using, then this will be a very hurtful change.
In the meantime, I do recommend that you keep a close eye to what is going on within this area as it will most likely affect you if you are running any application accounts, which you probably are, like Dynamics Portal, Forms Pro, Voice of the Customer and many more. If you go into the list of users and change view to “Application users” (or whatever it might be called in your language) you will see the list. I think Micrsoft will make some changes, or some announcements to this before October 1. Let’s see what.
Update 2019-09-04
There has been some chatter going around regarding this and do note the comments below which include interesting links and good thoughts. There are some additional points that need to be pointed out. Instead of changing the original article I will continue to add updates like these.
Normal UI usage will count
Initially I did not think that normal UI usage would count towards the API request calls. With “normal” in this case, as an old Dynamics 365/CRM geek, I of course mean a model driven App, but the same also goes for canvas Apps or actually any use of the CDS, what so ever. What this will mean when a user runs out of API requests, will be interesting to see. How many requests are used when the application is used, of course depends a lot on what you do. If you switch on F12 in Chrome you can check the network traffic and see for yourself.
Batching will be your friend
Using batching will from now on not only be a general best practice but also make you save money. If you use tools like Kingswaysoft this is easy to configure, to make sure that you have large batches when for instance doing CUD calls. When writing code directly, you will need to understand how to do this directly. Note that sometimes this will require entire rewrites of the code. I have seen programs off the shore of Orion that you wouldn’t believe with tons of single queries instead of one single call. Most often written by devs who have no or very little experience of writing code towards Dynamics 365/CDS.
Unclear if possible to move API-calls
As several people here and on Twitter have commented, it is probably incorrect to interpret that API:s can be moved from normal users to application users and non-interactive users. This will cause major headaches for some customers which will be struck with lots of additonal costs. Costs that are not very welcome as the per GB cost recently increased 800% hurting especially the larger customers with massive integrations and extensive use of the system. I do, for instance, have a customer that exceeds 1M requests per day 365 days a year. This would require them to buy over 100 addon 10k API requests SKU:s, despite the fact that their 500 users gives them a total of over 5M requests per day, something they will not be using through the UI unless someone is drinking very large amounts of coffee. – NEW Update: This was an incorrect interpretation. You cannot reallocate API calls from normal users.
The price is here
The price for the 10k/24h SKU will be $50/month. This means that for a customer like mine having major integrations causing around 1M API-calls per day, this would cost an additional per month $5 000 or yearly $60 000. I sincerely hope they will relax the throttling to make it worth it. If/when they do, I will read my Macciavelli again.
Update 2019-09-05
First of all I will write a new blog article on this, when the dust settles and we know what is going on. Currently there are quite a lot of unknowns and I wouldn’t be surprised if Microsoft announced a thing or two soon. I have been told that the FAQ will be updated in a couple of days.
Batching – again
There were some discussions on if batching actually were going to be useful in this case or not. I have now gotten confirmed that a batched request will be considered as one (1) call. This is both for batched Creates/Updates/Deletes and Queries of multiple records (that would be very strange if it wasn’t one record, but I had to ask).
Data Export Service etc.
Data Export Service and other services that run under the system account will not count towards the API request. This is good news as this opens up for many users to be able to use this method to offload the API:s for reads.
What is the competition up to
I checked to see how SFDC are handling this and as far as I can see they have a similar setup as can be read here:
I am no expert on their licensing model, but I think it is good to know that this isn’t just a PowerPlatform thing. However, there are some distinct differences:
The API calls are not counted for normal browser/client usage. Only “real” API calls.
They have real enforcement blocking an entire instance/org if they overshoot
All API:s per user license are summed up to the org level
Microsoft Addon apps will include request
If you buy Dynamics Portals, this will include some additional licenses. The same goes for Forms Pro. Hence there should be some default API request assignment to those application users that are installed. I do wonder if it would be financially beneficial to piggyback on those application users? There is also no current method for ISV:s to bundle API-requests into their product if they install an application user upon installation.
CSP / Distributor silence
We have still heard nothing of the 10k addon SKU from any distrubutor, EA or CSP. It will be interesting to see if it will reach the entire distribution chain by October 1 when customers will start being notified that they are in violation (new customers).
Tonight Microsoft rolled out an update to Dynamics 365 that seemed to have had a few issues. Most noteably if you have any Lookup-fields in a quickfind views “Find”-columns, it will break. Most of the time, not always. Microsoft knows about this, there are angry threads talking about this, like this one: https://community.dynamics.com/crm/f/117/t/301925?pi61802=3#responses
The temporary solution to get this working, or the essential parts for your system, is to remove the Lookup fields from your find columns for the entities that are breaking. This will of course have the effect that no searching can be done in this entity, but you can switch it on again later.
We have also done some preliminary tests and it seems like the UCI (Unified Interface) is not affected by this. So making a quick UCI App could also be a good, fast fix, especially for the most critical user groups.
Note also, that some lookups may break as they use the quickfind logic to search the related entity when you are inputing data. Hence if this happens, you might have to do an interim fix there too.
The error is a “SQL Error” and if you download the logfile, there are two different error messages that I have seen/heard of: (I changed the fieldname to “contactidName“)
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Xml.XmlException: Microsoft.Crm.CrmException: Sql error: ‘Invalid column name ‘contactidName’.’ at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) —> Microsoft.Crm.CrmException: Sql error: ‘Invalid column name ‘kuoni_BookingIdName’.’ at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) — End of inner exception stack trace — at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #BDDD78E5Detail: <OrganizationServiceFault xmlns:i=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://schemas.microsoft.com/xrm/2011/Contracts”> <ActivityId>64efc536-e25e-4e36-a163-dbe707b07302</ActivityId> <ErrorCode>-2147220970</ErrorCode> <ErrorDetails xmlns:d2p1=”http://schemas.datacontract.org/2004/07/System.Collections.Generic” /> <Message>System.Xml.XmlException: Microsoft.Crm.CrmException: Sql error: ‘Invalid column name ‘contactidName‘.’ at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) —> Microsoft.Crm.CrmException: Sql error: ‘Invalid column name ‘contactidName‘.’ at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) — End of inner exception stack trace — at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #BDDD78E5</Message> <Timestamp>2018-11-21T09:41:26.798591Z</Timestamp> <ExceptionRetriable>false</ExceptionRetriable> <ExceptionSource i:nil=”true” /> <InnerFault> <ActivityId>64efc536-e25e-4e36-a163-dbe707b07302</ActivityId> <ErrorCode>-2147204784</ErrorCode> <ErrorDetails xmlns:d3p1=”http://schemas.datacontract.org/2004/07/System.Collections.Generic” /> <Message>Sql error: ‘Invalid column name ‘contactidName‘.'</Message> <Timestamp>2018-11-21T09:41:26.798591Z</Timestamp> <ExceptionRetriable>false</ExceptionRetriable> <ExceptionSource i:nil=”true” /> <InnerFault i:nil=”true” /> <OriginalException i:nil=”true” /> <TraceText i:nil=”true” /> </InnerFault> <OriginalException i:nil=”true” /> <TraceText i:nil=”true” /> </OrganizationServiceFault>
Second error:
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Xml.XmlException: Microsoft.Crm.CrmException: A quick find filter cannot have any child filters at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) —> Microsoft.Crm.CrmException: A quick find filter cannot have any child filters at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) — End of inner exception stack trace — at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #48A7E659Detail: <OrganizationServiceFault xmlns:i=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://schemas.microsoft.com/xrm/2011/Contracts”> <ActivityId>fa29912a-47b8-42cf-8e7b-fe3e0c13aecc</ActivityId> <ErrorCode>-2147220970</ErrorCode> <ErrorDetails xmlns:d2p1=”http://schemas.datacontract.org/2004/07/System.Collections.Generic” /> <Message>System.Xml.XmlException: Microsoft.Crm.CrmException: A quick find filter cannot have any child filters at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) —> Microsoft.Crm.CrmException: A quick find filter cannot have any child filters at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute() at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData() at Microsoft.Crm.ApplicationQuery.ExecuteQuery() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder) at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData() at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData() at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData) at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) — End of inner exception stack trace — at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #48A7E659</Message> <Timestamp>2018-11-21T10:28:58.4053402Z</Timestamp> <ExceptionRetriable>false</ExceptionRetriable> <ExceptionSource i:nil=”true” /> <InnerFault> <ActivityId>fa29912a-47b8-42cf-8e7b-fe3e0c13aecc</ActivityId> <ErrorCode>-2147217118</ErrorCode> <ErrorDetails xmlns:d3p1=”http://schemas.datacontract.org/2004/07/System.Collections.Generic” /> <Message>A quick find filter cannot have any child filters</Message> <Timestamp>2018-11-21T10:28:58.4053402Z</Timestamp> <ExceptionRetriable>false</ExceptionRetriable> <ExceptionSource i:nil=”true” /> <InnerFault i:nil=”true” /> <OriginalException i:nil=”true” /> <TraceText i:nil=”true” /> </InnerFault> <OriginalException i:nil=”true” /> <TraceText i:nil=”true” /> </OrganizationServiceFault>
Gustaf Westerlund MVP, Founder and Principal Consultant at CRM-konsulterna AB www.crmkonsulterna.se
PowerApps or as the new name for it is, Canvas driven Apps, is a very fast low/no-code way of creating applications that can fill in the blanks where Dynamics 365 CE sometimes fit. Can for instance be when there is a mapping entity, a complex calendar functionality or even integrations with a camera or other applications directly. These things can be done, some are even supported within the new UI/UCI if you are running it through the tablet/mobile client. However, there is currently no easy way that I have found to just add a PowerApp/Canvas Drive App (I will just call it PowerApp below to make things easier) to Dynamics. But after a chat with my friend, ex MVP and now Microsoft Global Black Belt Carsten Groth (isn’t that a cool name for a team by the way?) he told me that it is possible to embed PowerApps. So I googled a bit a found that no one seemed to have blogged about this (if you have, please tell me in the comments) except for other it concerning other applications like SharePoint. I tried it out and found that it wasn’t that hard at all to embedd a PowerApp into Dynamics 365.
The first thing we have to start with is to create our PowerApp. You can get to this place by browsing to https://web.powerapps.com or clicking the waffle in Office365 and then selecting PowerApps. In my case, I used the Dynamics 365 template and pointed to the Case Entity and did more or less pressed Next-next-finnish. I did replace the field that was shown in the first screen from the Guid of the case to the field “title” as that makes a little bit more sense looking at.
So what I was looking for when creating the PowerApp was the AppId, in this case: “904e3ac1-1e26-4b4b-a384-971485f6709c“
What we then need is the embedding syntax for PowerApps which is: <iframe src=”https://web.powerapps.com/webplayer/iframeapp?source=iframe&screenColor=rgba(104,101,171,1)&appId=/providers/Microsoft.PowerApps/apps/[AppId]” />
You need to replace the [AppId] with your AppId. Also, if you do not specify it, the iframe it will typically render rather small so I would recommend either setting the size of it directly with width and height attributes or using css, the latter being more kosher.
I tried setting an Iframe directly with this in Dynamics 365, but that didn’t seem to work. All I got was a spinner like this:
Spinner which never stops when tried to add PowerApp directly
Not sure why this is.
So, I circumvented it and created a very small html-page like this:
This time, when trying the TestPowerApp.html-page from my local drive, the spinner was quickly replaced by this and then by the App
Then I uploaded this file as a webresource to Dynamics.
Create a webresource with the simple html-page pointing to the PowerApp
After uploading it, in the WebResource screen, you can test the page by clicking on the URL. It should show a webpage with the PowerApp.
The PowerApp running as a webresource in Dynamicws 365
Now you can use this web resource wherever you want. Like directly in a sitemap:
Added PowerApp webresource to the Marketing Area as a Subarea called “Power App Cases”
It should be possible to send parameters to the PowerApp as well making them context aware so that we can create PowerApps that for instance show up within a case and show specific data on that case after you have selected it in Dynamics 365. However, if you look at the iframe syntax you will see that the AppId and stuff is already a parameter and I need to research this a bit more to be able to figure it out. I think that the html web resource probably has to shuffle the query string parameters from Dynamics to PowerApps. I will leave this hanging and hope that someone else in the community catches this ball! Otherwise I will try to figure it out later.
As CDS (common data service) and Modular Driven Apps are the same thing as Dynamics 365, just with less sugar on top, this technique can be used there as well.
If you find anything unclear or have any questions, please leave a comment (moderated).
Gustaf Westerlund MVP, Founder and Principal Consultant at CRM-konsulterna AB www.crmkonsulterna.se
Recent Comments