We have migrated a CRM 2011 successfully to Dynamics 365, Version 9.
We have determined that the audit history for connections is not present in the UI.
Is it because the connection form is still in CRM 2011 style (out-of-the-box)? If so, where do you find the connection audit history?
Auditing is enabled in CRM, on the connection entity and also some fields are configured for auditing.
I would assume this is expected behavior & working as per design in various CRM versions.
Connection entity Form editor showing left navigation with "Audit History" menu.
Actual Connection form rendering is not showing the left navigation. I remember this was the case with CRM 2011 form also.
If you want to show the "Audit history" explicitly, you can always go for some unsupported solution like discussed here.
Keep an iframe & point the url something like this: (Obviously you have to script to parameterize it)
https://devcrm.crm.dynamics.com/userdefined/areas.aspx?formid=52078acf-77c4-4e18-86b8-ebffcafc0698&inlineEdit=1&navItemName=Audit History&oId={3877A32E-EA20-E911-A952-000D3A34E213}&oType=3234&pagemode=iframe&rof=true&security=852023&tabSet=areaAudit&theme=Outlook15White
Code from the above UG discussion link:
function buildIframeSource() {
var url = window.parent.Xrm.Page.context.getClientUrl();
var recordId = window.parent.Xrm.Page.data.entity.getId().replace("{", "").replace("}", "");
var element = document.getElementById("areaAuditFrame");
element.src = url + "/userdefined/areas.aspx?formid=52078acf-77c4-4e18-86b8-ebffcafc0698&inlineEdit=1&navItemName=Audit%20History&oId=%7b" + recordId + "%7d&oType=10270&pagemode=iframe&rof=true&security=852023&tabSet=areaAudit&theme=Outlook15White";
};
Related
I'm looking to change the default from user when an email is created. Setting it through a workflow doesn't work, and business rules does not allow to set the default from behavior. Has anyone been able to do this successfully?
I found this answer by stringing together a few different answers. Note: I couldn't find any documentation on official Microsoft Dynamics functionality, so although it worked for me on version 8 of Dynamics 365 (cloud) it could stop working in the future.
I created a javascript file that ran on load. If the form had form state, create, then I would use the following script to change the value:
function _setFromUser() {
var legalQueueID = "00000000-0000-0000-0000-000000000000";
var recordName = "Legal Contracts Queue";
var entityName = "queue";
Xrm.Page.getControl("from").getAttribute().setValue([{ id: legalQueueID, name: recordName, entityType: entityName }]);
}
Hope this helps someone else!
I am using crm 2016 and I need to clone a record using plugin, after googling I found out that I need to use Microsoft.Xrm.Client that hold the clone() function - which is not in 2016 SDK because of MS reorganization.This lib is in 2015 SDK.
My questions are :
1. If I'll take that lib from CRM 2015 and use it in 2016 will it be supported?
2. If it's not supported what are my options to clone a record in server side?
The method Clone() in the Microsoft.Xrm.Client only creates a copy of the Entity object in memory. It does not create a copy in the database of CRM. When you need to create a copy in the database just instantiate a new Entity object and pass it to the Create() method of the IOrganizationService interface.
When you really need a deep clone as described on MSDN you could consider writing one yourself. In most scenarios you will only need to copy the objects in the attributes collection. Of those objects only the reference types EntityReference, OptionSetValue and Money wiil need your special attention.
I would not advise to use deprecated libraries.
We use the following helper method to clone an entity - this is an updated version from the original which correctly clones the reference types, and excludes the system attributes
public static Entity CloneEntitySandbox(Entity entityToClone)
{
var newEntity = new Entity(entityToClone.LogicalName);
var systemAttributes = new List<string>();
systemAttributes.Add("createdon");
systemAttributes.Add("createdby");
systemAttributes.Add("modifiedon");
systemAttributes.Add("modifiedby");
systemAttributes.Add("owninguser");
systemAttributes.Add("owningbusinessunit");
foreach (var attribute in entityToClone.Attributes
.Where(x => x.Key != entityToClone.LogicalName + "id")
.Where(x => !systemAttributes.Contains(x.Key)))
{
switch (attribute.Value.GetType().Name)
{
case "Money":
var m = attribute.Value as Money;
newEntity[attribute.Key] = new Money(m.Value);
break;
case "EntityReference":
var er = attribute.Value as EntityReference;
newEntity[attribute.Key] = new EntityReference(er.LogicalName, er.Id);
break;
case "OptionSetValue":
var os = attribute.Value as OptionSetValue;
newEntity[attribute.Key] = new OptionSetValue(os.Value);
break;
default:
newEntity[attribute.Key] = attribute.Value;
break;
}
}
return newEntity;
}
Note that this does not perform the save to create the cloned entity in the CRM database, that's up to you.
Microsoft announcement says:
We also removed Microsoft.Xrm.Client from the CRM 2016 (8.x) SDK client because it was not compliant with the OAuth changes, and replaced it with Microsoft.Xrm.Tooling.Connector. You can use the current Microsoft Dynamics 365 Software Development Kit (SDK) to access Microsoft Dynamics CRM back to version 6.x for both auth and messaging.
Dynamics 365 SDK Backwards Compatibility
You can still use Microsoft.Xrm.Client.dll in your project from older SDK, this maybe supported for a while.
But I would recommend to go with custom Action, taking parent record as EntityReference Input parameter, Retrieve the parent record data + needed related entities & manually create (clone) child record + related entities records in Action.
You can Execute/invoke this Action from client/server side, wherever you want.
Does anyone know of a managed solution to import into Dynamics 365 that adds functionality for a custom button to copy the Guid of any entity to your clipboard?
In a previous environment we used this one
Of course this can't be imported into the newer Dynamics 365.
I know how to parse out the Guid from the URL, but the button to autocopy it to the clipboard was amazing.
The Chrome Extension Level Up has button for Record Id, or you can use the bookmarklet code. Just add the below code to a bookmark in your browser:
//get record id
javascript: (function () { var form = $("iframe").filter(function () { return $(this).css("visibility") == "visible" })[0].contentWindow; window.prompt("Copy to clipboard: Ctrl+C, Enter", form.Xrm.Page.data.entity.getId().slice(1, -1)) })();
Try Level Up for Dynamics 365 Chrome Extension, it provides a great variaty of common JScript actions and shortcuts to help with extensibility, diagnostics and administration
if what you need is to pulish an option to your user to get the GUID of a record and prevent the execution of other JS logic such as display all hidden attributes, then you will have to create a ribbon button and execute JS logic contained in a webresource, to make it compatible with CRM v9 and forward, past the execution context to your function (PrimaryControl) and call the native Xrm function executionContext.getFormContext().data.entity.getId()
Another extremely useful Chrome called Dynamics Power Pane. Use it together with Level Up for Dynamics 365 will be very powerful.
I am using MS CRM 2013 and created a custom filter on ownerid. It works ok but just that it returns both team and user. I just want to have user. If I provide the entityname as below:
Xrm.Page.getControl("ownerid")
.addCustomFilter(thisfetch, "systemuser");
Then it filters on user and returns filtered users and all teams.
How can I fix it?
thisfetch is my filter criteria.
Please help.
Instructing the Lookup dialog to only allow SystemUser is currently not supported.
There are unsupported workarounds but as pointed out in the linked article they can easily break due to changes in the DOM.
plain js
function setToFieldFilter()
{
document.getElementById("to_i").setAttribute("lookuptypenames", "systemuser:8:User");
document.getElementById("to_i").setAttribute("lookuptypes", "8");
}
function onLoad()
{
Xrm.Page.getControl("ownerid").addPreSearch(setToFieldFilter);
}
jquery
$("#to_i").attr("lookuptypenames", "systemuser:8:User");
$("#to_i").attr("lookuptypes", "8");
Sources
CRM 2013 : Change default entity for a Lookup field
Filter PartyList entities Lookup using Jscript in Microsoft Dynamics CRM 2011
In CRM 4.0 we could place dynamic content (aspx) in the ISV-folder in CRM, creating separate applications but with security and relative URLs to CRM, so for example a custom 360 view of account could be linked in an iframe using a relative URL along the lines of
/ISV/CrmMvcApp/Account.aspx/Overview?id=....
In CRM 2011 usage of the ISV folder is deprecated and Microsoft has some guidelines on how to transition into doing this in supported manner (MSDN gg309571: Upgrade Code in the ISV folder to Microsoft Dynamics CRM 2011). They say:
For scenarios that will not be satisfied by the Web resources feature, create your Web application in its own application pool with its own web.config.
The way I am reading this (coupled with the guidelines on supported/unsupported) is that we need a separate web site in IIS with its own binding as you are not allowed to add virtual directories etc. under the standard CRM app. This is unfortunate and does not allow relative paths/URLs in customizations and sitemap. This is troublesome especially when exporting and importing solutions from DEV, TEST and/or PROD.
Are my assumptions wrong?
Can we somehow have relative paths?
Have anyone else found a pragmatic and easy approach to having external content without doing the sitemap and customization changes for each environment?
EDIT: Confirmed with other sources that my understanding of the guidelines are correct, as this is also listed in the list of unsupported changes. Virtual folders and web apps are to be kept totally separated from the default CRM web site.
Creating an Internet Information Services (IIS) application inside the Microsoft Dynamics CRM website for any VDir and specifically within the ISV folder is not supported.
MSDN gg328350: Unsupported Customizations
If you primarily need to access CRM data/records, take a look at using a jScript web resources. You can do "most" CRUD operations using the REST OData services. If you use JQuery to parse the JSON it's very productive.
I have found a solution much like the javascript redirect, without the need for client execution and only configuring the environment details (servername, port) once. Additional logic can easily be added.
The solution creates a dependency into the customizations, but not an environment one like and can be used for unmanaged and managed solutions.
The solution was to place a file Redirect.aspx in the ISV folder. The code does not in any way interact with CRM and falls within the supported guidelines, however the solution is not future proof as the ISV folder is deprecated by Microsoft.
Redirect.aspxwill automatically pass along any parameter passed, so will work with or without the entity identifiers and so on.
Usage:
Place the file in the ISV folder on the CRM app server
Change the server name and port to match the current environment (must be done for each environment)
In customizations, for example for an iframe, use the following as a source:
/ISV/Redirect.aspx?redirect=http://SERVERREPLACE/CustomMvcApp/SomeControllerAction
Here is the content of Redirect.aspx
<%# Page Language="C#" %>
<html>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
// must be customized for each environment
const string ServerBaseName = "appserver1:60001";
const string UrlParameterName = "redirect";
const string ReplacePattern = "SERVERREPLACE";
var parameterUrl = Request.Params[UrlParameterName].Replace(ReplacePattern, ServerBaseName);
var queryStringBuilder = new StringBuilder();
foreach (var key in Request.QueryString.AllKeys)
{
if (key == UrlParameterName)
{
continue;
}
queryStringBuilder.Append(!(queryStringBuilder.Length > 0) ? "?" : "&");
queryStringBuilder.Append(key + "=" + Request.QueryString[key]);
}
var completeRedirectString = parameterUrl + queryStringBuilder;
Response.Redirect(completeRedirectString);
}
</script>
<head>
<title>Redirecting</title>
</head>
</html>
Not quite "relative urls" as per your question, but a solution I use is to store "stub" or "root" urls in a config entity and read those records in JScript at runtime to determine the fully qualified destination for your custom links.