03/06/2020

MS CRM How to convert UTC to local date with daylights savings

Before you connect to CRM Database, you need to make sure the user which you are using to login to SQL management Studio has permissions and the entities and also the personal profile of the user in CRM has the current local date and timezone

In order to change the personal profile timezone, login to CRM and click on settings to customize your time zone:



Now when you connect to CRM SQL Database with the user, your personal profile already have a timezone different from UTC (potentially)

Here is the snippet which you can user to convert the UTC date value to your local timezone regardless of day light savings


 
/* mi us your date field in UTC */
DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), LastModified) AS LastModifiedLocal

17/07/2015

Staff who have actively used CRM in the past 30 days

Staff who have actively used MS CRM in the past 30 days 


(Please leave your feedback if you find this useful)

In order to have a list of users who logged into CRM in the last 30 days, we should start by having a look at the audit history of a user in CRM:


As you can see the Audit history shows the last login date.
So all we have to do is to run a select on audit records to retrieve the last month’s “ObjectId” and name of the users.
 Here is the select statement:

SELECT dbo.Audit.ObjectId, dbo.FilteredSystemUser.fullname,  dbo.FilteredSystemUser.isdisabledname,
MAX(DATEADD(HOUR,10,dbo.Audit.CreatedOn)) as [Last Date Accessed]
FROM            dbo.Audit WITH (nolock) INNER JOIN
                         dbo.FilteredSystemUser  (nolock) ON dbo.Audit.ObjectId = dbo.FilteredSystemUser.systemuserid
WHERE        (dbo.Audit.Action = 64) AND (dbo.Audit.CreatedOn >= dateadd(m, -1, getdate()) )
group by dbo.Audit.ObjectId, dbo.FilteredSystemUser.fullname, dbo.FilteredSystemUser.jobtitle, dbo.FilteredSystemUser.isdisabledname

Order by dbo.FilteredSystemUser.fullname




12/11/2014

MS CRM 2011 Roll-up 12 - IE10 - ActiveXObject("Msxml2.DOMDocument") is not supported anymore

If you are using ActiveXObject("Msxml2.DOMDocument") or trying to get the XML results and use XmlDoc.selectNodes running a FetchXML after upgrading to IE10 the code will break.

Sample:

We used to be able to pass a FetchXML to this function and get "workflowid" which then we were running the dialog box for the user.

Old Code looked like this:


//This is the FetchXML code to extra the live guids of the workflows
function Fetch(xml) {
    var Xml = ""
    Xml += GenerateAuthenticationHeader()
    Xml += "";
    Xml += "";
    Xml += "";
    Xml += FetchEncode(xml); // Microsoft _HtmlEncode function  
    Xml += "";
    Xml += "";
    Xml += "";
    Xml += "";
    var XmlHttp = CreateXmlHttpObject(); // Microsot CreateXmlHttp function  
    XmlHttp.open("POST", "/mscrmservices/2007/crmservice.asmx", false); //Sync Request  
    XmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    XmlHttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
    XmlHttp.send(Xml);

    var XmlDoc = new ActiveXObject("Msxml2.DOMDocument");
    XmlDoc.async = false;
    XmlDoc.resolveExternals = false;
    XmlDoc.loadXML(XmlHttp.responseXML.text);

    var resultRecords = XmlDoc.selectNodes("//workflowid");
    return resultRecords[0].text;
}

Upgrading to IE10 and we have noticed the selectNodes function returns null. Here is a way we have temporarily replaced the funtionlity by using a JQuery call and pass the SOAP message to the 2007 endpoint:

//This is the FetchXML code to extra the live guids of the workflows
function Fetch(xml) {

    var Xml = ""
    Xml += GenerateAuthenticationHeader()
    Xml += "";
    Xml += "";
    Xml += "";
    Xml += FetchEncode(xml); // Microsoft _HtmlEncode function  
    Xml += "";
    Xml += "";
    Xml += "";
    Xml += "";

    // the code has been Modified in regards to compatibility issue with IE10
    // The end point needs to be replaced with 2011 version and the following with OData call
    var soapURL = "/mscrmservices/2007/crmservice.asmx" 

    var returnValue;

    $.ajax({
        type: "POST",
        contentType: "text/xml; charset=utf-8",
        datatype: "xml",
        async: false,
        url: soapURL,
        data: Xml,
        beforeSend: function (XMLHttpRequest) {
            XMLHttpRequest.setRequestHeader("Accept", "application/xml, text/xml, */*");
            XMLHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
            XMLHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
        },
        success: function (data, textStatus, XmlHttpRequest) {
            var resp = $.parseXML($(XmlHttpRequest.responseXML).children().find('FetchResult')[0].textContent).childNodes[0];
            if (resp != null && resp.childNodes[0] != null && resp.childNodes[0].childNodes[0] != null)
            {
                returnValue = resp.childNodes[0].childNodes[0].textContent;
                //$.parseXML($(XmlHttpRequest.responseXML).children().find('FetchResult')[0].textContent).childNodes[0].childNodes[0].childNodes[0].textContent
            }
            else
            {
                alert("failure unable to perform this action.");
                returnValue = "failure";
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            returnValue = 'failure' + errorThrown;
            alert("failure " + errorThrown);
        }
    });

    return returnValue;
}

04/09/2014

Cannot save a disabled control on CRM form

Cannot save a disabled control on CRM form 

Suppose you have used the following function to “Disable” a field

Method:

    /*
    * SetDisabledField
    * To disable/enable field by field id and isDisabled flag
    * fieldId --> field id
    * isDisabled --> true or false
    */
    SetDisabledField: function (fieldId, isDisabled) {
        var fieldID = Xrm.Page.ui.controls.get(fieldId);
        if (fieldID != null)
            fieldID.setDisabled(isDisabled);
    },
And you have called the method as:

SetDisabledField('new_revenue', false);
Now in case you have changed the value of the field before you disabled it, clicking on save will not include this attribute and as a result the value will not change!

Solution:

Change the submit mode to always will “always” send the attribute into the message and it will be saved regardless:
Xrm.Page.getAttribute('new_revenue').setSubmitMode('always');


From SDK


setSubmitMode
Sets whether data from the attribute will be submitted when the record is saved.
Attribute Types: All
JScript 
attributeObj.setSubmitMode()
Arguments
Type: String
One of the following values:
·         always
·         never
·         dirty
Example: The SDK.AttributeSamples.submitAllOptionsetData function will force all optionset attributes to be submitted. This is confirmed by checking getDataXml and displaying the result in an alert.
JScript 
SDK.AttributeSamples.submitAllOptionsetData = function () {
 var attributes = Xrm.Page.data.entity.attributes.get(SDK.AttributeSamples.isOptionSet);
 for (var i in attributes) {
  attributes[i].setSubmitMode("always");
 }

 alert(Xrm.Page.data.entity.getDataXml());
};

23/07/2014

How to Debug CRM 2011 Post Rollup 15 Javascript

How to Debug CRM 2011 Post Rollup 15 Javascript


Post Rollup 15 Microsoft CRM Dynamics is loading the web resources in a different way,
The Javascripts are now downloaded into the client browser as a dynamic block, hence the traditional ways of debugging CRM would not work.

How to Debug in IE:

(1) Open the form and press F12
(2) Select Script from the top and Select FromScript.js.aspx?...



(3) Find “function crmFormOnLoadHandler(){” and find you "Onload" (for instance) method few lines below it, add a break point to your on load function

(4) Click on “Start debugging” and refresh the CRM form


17/07/2014

CRM Dynamics 2011 Plug-in assembly does not contain the required types or assembly content cannot be updated.

Plug-in assembly does not contain the required types or assembly content cannot be updated. 

On registering a plugin using plugin registration tool, you might get this error. Here is more details on the error: Plug-in assembly does not contain the required types or assembly content cannot be updated. 

Detail: -2147204725 CallStack at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.Pipeline.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.MessageProcessor.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.InternalMessageDispatcher.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion) at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, Boolean traceRequest, OrganizationContext context, Boolean returnResponse) at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Update(Entity entity, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) Plug-in assembly does not contain the required types or assembly content cannot be updated. 2014-07-16T22:10:31.8203518Z -2147204725 CallStack at Microsoft.Crm.CrmPluginAssemblyMetadata.GetPluginTypeMetadata(String typeName) at Microsoft.Crm.ObjectModel.PluginTypeValidator.ValidateInternal() at Microsoft.Crm.ObjectModel.PluginValidatorBase.Validate() at Microsoft.Crm.ObjectModel.AssemblyDataCanBeUpdatedValidator.ValidateInternal() at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.VerifyRegistrationAbility(IBusinessEntity pluginAssembly, Boolean createCall, ExecutionContext context) at Microsoft.Crm.ObjectModel.SdkEntityServiceBase.UpdateInternal(IBusinessEntity entity, ExecutionContext context, Boolean verifyAction) at Microsoft.Crm.ObjectModel.PluginAssemblyServiceInternal`1.Update(IBusinessEntity entity, ExecutionContext context) Plug-in assembly does not contain the required types or assembly content cannot be updated. 2014-07-16T22:10:31.8203518Z Server stack trace: at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Microsoft.Xrm.Sdk.IOrganizationService.Update(Entity entity) at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.UpdateCore(Entity entity) at Microsoft.Crm.Tools.PluginRegistration.RegistrationHelper.UpdateAssembly(CrmOrganization org, String pathToAssembly, CrmPluginAssembly assembly, PluginType[] type) at Microsoft.Crm.Tools.PluginRegistration.PluginRegistrationForm.btnRegister_Click(Object sender, EventArgs e) 

Reason? 

There could be many reasons for this error message which I am sure there are many articles on the Net talking about it. This was the scenario we faced:

The Plugin which has been registered previously, had a step which has been removed from the assembly! Suppose you have register the plugin assembly with three steps A, B and C. you have then forgot to remove Step B from CRM but you have deleted the corresponding plugin class (The scenario we faced was really we wanted to register the same plugin on a backup org which has an extra step)) 
Hence when you register compiled the new plugin, CRM expects to get "Step B" during plugin update! but considering the class for Step B has been removed and the new assembly does not have it, it throws the error.

How to Solve? 

You need to find out which step needs to be unregistered from the assembly steps before you can update the plugin assembly. If in TFS try to review the history to see what class has been removed and delete the corresponding plugin steps.

16/07/2014

Sample CRM 2011 Plugin on Contact

Suppose we want to write a plugin which fires on Update and on Insert to populate Nickname with the first name it’s empty. The plugin is quite straight forward on Insert of the record if the target does not contain nickname it means the user hasn’t provided any value. For update, one way is to compare Pre Image with Post Image to see if the value of nickname is changed. However, the easier option is to have a look at the target message, if preferredname is not in the message it means it hasn’t been updated, however if it is in the message and it’s “empty” it means the user set it to empty and clicked on save. The target entity will contain all the fields which has been changed and they are empty if the attribute has been emptied out.

 
using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hooman.Crm.Plugins.Common;
using Hooman.Enterprise.Integration.DynamicsCrm;
using Enums = Hooman.Enterprise.Integration.DynamicsCrm.Enumerations;

namespace Hooman.Crm.Plugins.MAMR2.Contact
{
    /// 
    /// This plugin is responsible for populating Contact's Preferred Name when the record is been created or updated with no preferred name.
    /// 
    /// PostOperation-Create and PostOperation-Update (PreImage) of contact
    /// 
    public class ContactPopulatePrefferedNameWithFirstName : IPlugin
    {
            public void Execute(IServiceProvider serviceProvIder)
            {
                try
                {
                    // Get plugin execution context
                    IPluginExecutionContext context = serviceProvIder.GetPluginExecutionContext();

                    // Get tracing service
                    ITracingService tracingService = (ITracingService)serviceProvIder.GetService(typeof(ITracingService));

                    // Obtain the organization service reference
                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvIder
                                                                    .GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                    //The plugin should be registered for create and update of a contact
                    if ((context.MessageName == Messages.Create || context.MessageName == Messages.Update) && context.Stage == Stages.PostOperation)
                    {
                        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                        {
                            Entity target = ((Entity)context.InputParameters["Target"]);
                            tracingService.Trace("UpdateContactPreferredName. Starting message processing");

                            //Check if the plugin registered on contact
                            if (target.LogicalName.EqualsIgnoreCase(Hooman.Enterprise.Integration.DynamicsCrm.Contact.EntityLogicalName))
                            {
                                tracingService.Trace("UpdateContactPreferredName. creating service context");

                                // I have a wrapper class but you can create your own notmal CRM Service Context instead
                                var crmServiceContext = new CrmServiceContextWrapper(new CrmServiceContext(service));
                                Hooman.Enterprise.Integration.DynamicsCrm.Contact contactEntity 
                                    = target.ToEntity();
                                tracingService.Trace("UpdateContactPreferredName. retirve contact from context.");
                                contactEntity = crmServiceContext.ContactSet.FirstOrDefault(c => c.ContactId == target.Id);

                                // If Preferred Name (NickName) is not in the message and previously empty, update it with FirstName
                                tracingService.Trace("UpdateContactPreferredName. Update the nickname (Preferred Name) with first name.");

                                // on create if the nickname is not in the target message we will populate it from firstname
                                if (context.MessageName.EqualsIgnoreCase(Messages.Create) && !target.Contains("nickname"))
                                {
                                    tracingService.Trace("UpdateContactPreferredName. On create populate the nickname (Preferred Name) with first name.");
                                    target["nickname"] = target["firsname"];
                                }
                                // If the plugin fired on update
                                // if target entity we have recieved does not have nickname and the value in CRM is already emtpy populate it 
                                // with the first name
                                // or if nickname is in the target and is empty (the user deliberately emptied it out) populate it with the first name
                                else if (context.MessageName.EqualsIgnoreCase(Messages.Update) &&
                                    ((!target.Contains("nickname") && contactEntity.NickName == null && contactEntity.FirstName != null)
                                        ||
                                     (target.Contains("nickname") && target.Attributes["nickname"].ToString() == string.Empty)))
                                {
                                        tracingService.Trace("UpdateContactPreferredName. Update the nickname (Preferred Name) with first name.");
                                        target["nickname"] = contactEntity.FirstName.ToString();

                                        tracingService.Trace("UpdateContactPreferredName. about to update the service context.");
                                        service.Update(target);
                                 }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Throw an error message to be displayed in a dialog of the Web application.
                    throw new InvalidPluginExecutionException(Utils.BuildError(ex));
                }
            }
        }
}

02/04/2014

SQL Server: How to select table rows in one line?

This is a very good article for an easy way to convert rows in a table to linear data. For instance in CRM if you have multiple rows for Contact languages, you can write a select statement and who all the languages attached to a contact in one row with commas:

http://sqlwhisper.wordpress.com/2013/03/24/stuff-and-for-xml-path-for-string-concatenation/

14/03/2014

Play with LINQ in CRM - How to Subtract ListA from ListB

Suppose we have two LINQ query result sets ListA and ListB and both have a field called ContactId and we want to get records in ListA which does not exists in ListB:

Here is the Code:

ListA.RemoveAll(x => ListB.Exists(temp => temp.ContactId == x.ContactId));

28/02/2014

CRM 2011: Plug-in assembly does not contain the required types or assembly content cannot be updated


This error message might have various meanings; here is the problem I had and how I resolved it:

Problem: 

on registering a plugin assembly by using plugin registration tool system throws this error:

“Plug-in assembly does not contain the required types or assembly cannot be updated”


Not a very clear message and it took us some time to figure out what happened. We have a team of 5 developers using TFS to implement the code, when I wanted to register the plugin, I've got the latest version from TFS and build the assembly.


How to solve:

When you are trying to register your plugin #2, you can see the plugins within the assembly, compare the plugins with the ones that are registered and you may find out the registered assembly has extra plugins which does not exists in the assembly you are trying to register.



We had this issue because one of our team embers registered the assembly but did not checked the latest version in TFS so when I got the latest version from TFS there was a plugin missing from my assembly in compare of the one her registered before.

PLEASE COMMENT IF THIS WORKED FOR YOU 



20/01/2014

CRM dates how to convert to local time with daylight savings

There are many occasions such as reports that we want to show a date field in CRM and convert it to local time with daylight savings.

Thanks to one of my colleagues add this to your SELECT statement and it will convert a CRM date time field to local time and consider daylight saving:

DATEADD(HOUR,CAST(left(right(CAST(SYSDATETIMEOFFSET()as nvarchar(50)), 5),2) as INT),new_CRMDateTimeField)

19/12/2013

Sublime Text a Useful Text Editor

Many of us went through the scenario where you extract records out of CRM and have them as a csv/excel sheet and you want to create a comma delimiter file out of the records.

Here is how:

We have a list of numbers in an excel file where we want to create a comma separated list from all the Member Ids.


For instance we have the following excel sheet:



We want to create a comma separated file only from MemberId column First select the column in excel copy and paste the results in sublime text editor


Now select the end of the first line using shift + arrow keys, this will highlight the selected space at the end of the first line:


Now press Alt+F3, this will enforce the same selection on “all of the lines” within the file

then type comma (“,”) and viola!  

It added a comma at the end of every line :)





17/11/2013

Coding for retrieving Audit History in Microsoft Dynamics CRM 2011

For retrieving from the Audit history we need to use “RetrieveRecordChangeHistoryResponse”.
The following sample (which I partially found something similar in the SDK) retrieves the information of the Audit history for any object in CRM

Create Organization Service Proxy
        static void Main(string[] args)
        {

            try
            {
               //Grab the organization service url by navigating to
               // Settings -> Customizations - > Developer Resources
               // CrmInstance.CrmServer URL for your CRM
               //CrmInstance.cc create a new ClientCredentials and pass your user name/password and domain
             using (var XrmProxy = new OrganizationServiceProxy(new Uri(CrmInstance.CrmServer + "/XRMServices/2011/Organization.svc"), null, CrmInstance.cc, null))
                {
                    ExtractFromAudit(XrmProxy);
                    Console.WriteLine("Thank you for participating in this amazing experiment! muwhaha!");
                    Console.ReadLine();
                 }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.ReadKey(true);
            }
        }
ExtractFromAudit Method
        private static void ExtractFromAudit(OrganizationServiceProxy XrmProxy)
        {
            // The GUID of the object you want to retirve in this case i am passing contactid
            var entityId = new Guid("4DC98353-CF88-E011-87E1-005056B30007");

            Console.WriteLine("Retrieving the change history.\n");
            // Retrieve the audit history for the account and display it.
            RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest();
            changeRequest.Target = new EntityReference(Contact.EntityLogicalName, entityId);

            RetrieveRecordChangeHistoryResponse changeResponse =
                (RetrieveRecordChangeHistoryResponse)XrmProxy.Execute(changeRequest);

            AuditDetailCollection details = changeResponse.AuditDetailCollection;

            foreach (AttributeAuditDetail detail in details.AuditDetails)
            {
                // Display some of the detail information in each audit record. 
                DisplayAuditDetails(detail);
            }
        }
DisplayAuditDetails (found in CRM SDK and modified a bit)
/// 
        /// Displays audit change history details on the console.
        /// 
        /// 
        private static void DisplayAuditDetails(AuditDetail detail)
        {
            // Write out some of the change history information in the audit record. 
            Entity record = detail.AuditRecord;

            Console.WriteLine("\nAudit record created on: {0}", record["createdon"]);
            Console.WriteLine("Entity: {0}, Action: {1}, Operation: {2}",
                record.LogicalName ,record.FormattedValues["action"],
                record.FormattedValues["operation"]);

            // Show additional details for certain AuditDetail sub-types.
            var detailType = detail.GetType();
            if (detailType == typeof(AttributeAuditDetail))
            {
                var attributeDetail = (AttributeAuditDetail)detail;

                // Display the old and new attribute values.
                foreach (KeyValuePair attribute in attributeDetail.NewValue.Attributes)
                {
                    String oldValue = "(no value)", newValue = "(no value)";

                    //TODO Display the lookup values of those attributes that do not contain strings.
                    if (attributeDetail.OldValue.Contains(attribute.Key))
                        oldValue = attributeDetail.OldValue[attribute.Key].ToString();

                    newValue = attributeDetail.NewValue[attribute.Key].ToString();

                    Console.WriteLine("Attribute: {0}, old value: {1}, new value: {2}",
                        attribute.Key, oldValue, newValue);
                }

                foreach (KeyValuePair attribute in attributeDetail.OldValue.Attributes)
                {
                    if (!attributeDetail.NewValue.Contains(attribute.Key))
                    {
                        String newValue = "(no value)";

                        //TODO Display the lookup values of those attributes that do not contain strings.
                        String oldValue = attributeDetail.OldValue[attribute.Key].ToString();

                        Console.WriteLine("Attribute: {0}, old value: {1}, new value: {2}",
                            attribute.Key, oldValue, newValue);
                    }
                }
            }
            Console.WriteLine();
        }
Sample Results:

26/07/2013

CRM 2011 - What Entities each Security role have access to

The following SQL statement will retrieve a list of security roles and the level of access each security role has in regards to entities. this will be useful for scenarios when you  want to see who has "Delete" permissions on "Contacts" for instance.

Simply run the select query against the CRM database

SELECT DISTINCT
  FilteredRole.name, EntityView.PhysicalName AS [Entity Name],
  CASE Privilege.AccessRight WHEN 1 THEN 'READ' WHEN 2 THEN 'WRITE' WHEN 4 THEN 'APPEND' WHEN 16 THEN 'APPENDTO' WHEN 32 THEN 'CREATE' WHEN 65536
                       THEN 'DELETE' WHEN 262144 THEN 'SHARE' WHEN 524288 THEN 'ASSIGN' END AS [Access Level],
  CASE PrivilegeDepthMask WHEN 1 THEN 'User' WHEN 2 THEN 'Business Unit' WHEN 4 THEN 'Parent: Child Business Unit' WHEN 8 THEN 'Organisation' END AS [Security Level]
FROM         
RolePrivileges INNER JOIN
FilteredRole ON RolePrivileges.RoleId = FilteredRole.roleid INNER JOIN
PrivilegeObjectTypeCodes ON RolePrivileges.PrivilegeId = PrivilegeObjectTypeCodes.PrivilegeId INNER JOIN Privilege ON RolePrivileges.PrivilegeId = Privilege.PrivilegeId INNER JOIN EntityView ON EntityView.ObjectTypeCode = PrivilegeObjectTypeCodes.ObjectTypeCode
ORDER BY FilteredRole.name, [Entity Name]

Results

02/01/2013

Debugging JScript in Microsoft CRM Dynamics 2011

How to debug your JavaScript

The following include steps we should follow to prepare IE to debug JScripts in a CRM dynamics forms:

Enabling the Every Visit to the Page Feature

  1. Start Internet Explorer. 
  2. Select Tools, and then Internet Options. 
  3. On the General tab in the Browsing history section, click Settings. 
  4. Enable the Every time I visit the webpage option. 
  5. Click OK. 

Setting Script Debugging and Friendly Errors Options

  1. Start Internet Explorer. 
  2. On the Tools menu, click Internet Options. 
  3. Click the Advanced tab. 
  4. Clear the Disable script debugging (Internet Explorer) option. 
  5. Clear the Show friendly HTTP error messages option. 
  6. Click OK.

Debugging

Now simply add debugger; Jscript command in your Jscript from event.

Sample:
 
if (typeof (Account) == "undifined") {Account = {};}

//*****************************//
/* Main Account From Namespace */
//****************************//
Account.DefaultForm =
{
    CREATE_FORM_TYPE : 1,

    //*********** on Load **************//
    OnLoad: function()
    {
        debugger;
        Alert('OnLoad function of the Account Default form starts here');

    },
    //*********************************//
};
Publish your webresource and refresh the browser.
When you trigger the webresource (e.g. loading account form in the above sample code) the browser will show you a dialog box where you can debug your code in visual studio.

17/12/2012

Error CRM Dynamics: Unable to cast object of type 'Microsoft.Xrm.Sdk.Entity' to type

Here is when I have experienced this problem:

I have created a console app in VS 2012 added references and created my organization service as following:
  
            ClientCredentials clientCredentials = new ClientCredentials();
            clientCredentials.UserName.UserName = "YourAdminUserName";
            clientCredentials.UserName.Password = "YourPassword";


            OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(
                new Uri("https://OnlineCRMSample.api.crm5.dynamics.com/XRMServices/2011/Organization.svc"),
                null,
                clientCredentials, null);
            
              orgProxy.Authenticate();

            var _service = (IOrganizationService)orgProxy;
Up to here you have created your Organization service and you can simple use organization service to create/retrieve and update objects from CRM. for instance this will add an account:
 
            Entity account = new Entity("account");
            account.Attributes["name"] = "MySoopaDoopaAccount";

            _service.Create(account);
However I wanted to use early binding classes instead of using late-bound. Hence, first I've generated the classes using CrmSvcUtil.exe shipped in the Bin folder of the SDK:
C:\SDK\sdk\bin>crmsvcutil.exe /url:https://YouronlineCRM.api.crm5.dynamics.com/XRMSe
rvices/2011/Organization.svc /username:youruserName /passwor
d:YourPassword /serviceContextName:HoomanContext /namespace:Hooman /out:Generat
edCode.cs
This generated a cs file calls "GeneratedCode" which I have added to my console app and used the following line to extract the list of active contacts:
            //--- Creating Service Context --//
            var context = new HoomanContext(_service);

            //----------- Extract the list of active contacts --------------//
            var contacts = context.ContactSet.Where(c => c.StateCode == ContactState.Active).ToList();

            foreach (var c in contacts)
            {
                Console.WriteLine(c.FirstName + " " + c.LastName);
            }

            Console.WriteLine("Done!");
            Console.ReadKey(true);
But I have received this following error message: Unable to cast object of type 'Microsoft.Xrm.Sdk.Entity' to type 'Hooman.Contact'.

How to Solve it?

Use enableProxyTypes method on your Organization Service proxy to fix it, here is the sample for generating organization service proxy properly:

 
            orgProxy.EnableProxyTypes();

            orgProxy.Authenticate();

            var _service = (IOrganizationService)orgProxy;

16/12/2012

CRM Dynamics 2011 : ID3011: Unrecognized RequestType specified: 'http://schemas.xmlsoap.org/ws/2005/02/trust/Issue'

Problem:

You have downloaded a CRM Dynamics 2011 sample and by running the code you get this error: ID3011: Unrecognized RequestType specified: 'http://schemas.xmlsoap.org/ws/2005/02/trust/Issue'

Solution

The sample code is referencing the older versions of SDK dlls. Remove "microsoft.crm.sdk.proxy" and "microsoft.xrm.sdk" and add references to the latest SDK dlls.

15/12/2012

CRM Dynamics 2011 - Loading data from csv File

There are many ways to load external data and pump it to CRM dynamics. The following is a convenient way of loading a csv file (Accounts) and import them into CRM Dynamics 2011 Accounts entity:

Loading the CSV file into a DataTable

The following method accepts a csv file name and directory, load the data using odbc connection to the file and returns a DataTable
        
public static DataTable GetDataTableForCSV(string csvDirectory, string csvFileName)
        {

            OdbcConnection dbConn = new OdbcConnection("Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" + csvDirectory + ";");
            dbConn.Open();
            string dbName = "[" + csvFileName + "]";
            string sql = @"select * from " + dbName;
            OdbcDataAdapter dbCmd = new OdbcDataAdapter(sql, dbConn);
            DataSet dataSet = new DataSet(dbName);
            dbCmd.Fill(dataSet, dbName);
            dbConn.Close();
            return dataSet.Tables[0];
        
        }
 

Load the data into MS CRM Dynamics 2011 Accounts

The following is a sample of importing accounts from csv file into MS Dynamics 2011 assuming you have already built your OrganizationServiceProx (_service in this sample)

        static  void Main(string[] args)
        {

            //Creation of Organization Service porxy is omited for simplicity
            DataTable accounts = GetDataTableForCSV("C:\\MyCSVFile\\Sample\\","accounts.csv");

            //we have loaded the data from csv into accounts DataTable
            // lets iterate through and add them to our CRM Account entity
            foreach (DataRow rowItem in accounts.Rows)
            {
                Entity account = new Entity("account");
                account.Attributes["name"] = rowItem["Name"];
                _service.Create(account);
            }

            Console.WriteLine("Click  to continue");
            Console.Read();

        }

10/12/2012

Sample Code - CRM Using Organization Service Proxy

There are many ways to write code against CRM. One of the very easy ways is to use late-bound objects and use organization service proxy.

You first need to create a CRM organization proxy, then use late-bound entity object and set the attributes and then save it through the generated proxy.

With just a few lines in this sample code, you can create an "Account" in CRM 2011:

Create a Console App



Add References

Add the following references to your project

Micorosoft.Crm.Sdk.Proxy (from CRM SDK bin folder)

Micorosoft.Crm.Sdk (from CRM SDK bin folder)

System.ServiceModel

System.Runtime.Serialization


Add Using statements

The following namespaces should be added to the using section of your code

using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk.Client;

using Microsoft.Xrm.Sdk;


Sample code: Creating and Account


        static void Main(string[] args)
        {
            //Grab the organization service url by navigating to
            // Settings -> Customizations - > Developer Resources
            // The following is from online CRM org
            Uri oUri = new Uri("https://yourorg.api.crm5.dynamics.com/XRMServices/2011/Organization.svc");
            //** Your client credentials 
            ClientCredentials clientCredentials = new ClientCredentials();
            clientCredentials.UserName.UserName = "YourAccount.onmicrosoft.com";
            clientCredentials.UserName.Password = "YourAdminPassword";

            //Create your Organization Service Proxy
            OrganizationServiceProxy _serviceProxy = new OrganizationServiceProxy(
                oUri,
                null,
                clientCredentials,
                null);

            //** Now simple use Entity and create a sample account
            Entity entity = new Entity("account");
            entity.Attributes["name"] = "This is my sample account";

            //use the service proxy to create the entity object
            _serviceProxy.Create(entity);

            Console.WriteLine("Welldone SuperNova!");
            Console.ReadKey(true);
        }

09/12/2012

Connecting to CRM Online with Visual Studio 2012 and Windows 8


You have created your trial CRM online org and you want to write a code to show the org name of the newly created CRM org. Here is a brief overview on how to do it:

Turning on Windows Identity Foundation 3.5


From the control panel, click on Programs and Feature, click “Turn windows features on or off” and enable Windows Identity Foundation 3.5

 Note: Skipping this step will result the following error message:
"Could not load file or assembly 'Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=xxxx or one of its dependencies. The system cannot find the file specified."

Create a new Console application in visual studio 2012


 

Right click on your newly created project and choose add existing item and choose “deviceidmanager” class from the CRM SDK helper files

“{Your downloaded SDK location}\samplecode\cs\helpercode

Your project may look like this at this stage

 

Right click on the references folder and add the following assemblies

  • System.ServiceModel
  • System.Security (otherwise you will get at least this error: the name "ProtectedData" does not exist in the current context) 
  • Microsoft.xrm.sdk (From CRM SDK)

Add the following using statements:

//Namespcae of deviceidmanager class you have added

using Microsoft.Crm.Services.Utility;

//You have referenced System.ServiceModel for ClientCredentials

using System.ServiceModel.Description;

//You have referenced microsoft.xrm.sdk for DiscoveryServiceProxy

using Microsoft.Xrm.Sdk.Client;

//For request and response for retrieving your CRM online org

using Microsoft.Xrm.Sdk.Discovery;

The following code will retrieve the org name from your CRM online version

 

 
 
 
class Program
    {
        static void Main(string[] args)
        {
            string discoveryURL = "https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc"; 
            ClientCredentials deviceCredentials = DeviceIdManager.LoadOrRegisterDevice();
            ClientCredentials credentials = new ClientCredentials();
            //When creating a CRM online trial version, through Microsoft Online services you will setup a username and password
            credentials.UserName.UserName ="YourOnlineUserName.onmicrosoft.com";
            credentials.UserName.Password = "YourPassword";

            DiscoveryServiceProxy dsp = new DiscoveryServiceProxy(
                new Uri(discoveryURL),
                null,
                credentials,
                deviceCredentials
                );

            // try to authenticate
            dsp.Authenticate();

            //create a request and response to retrive your Org
            RetrieveOrganizationsRequest req = new RetrieveOrganizationsRequest();
            RetrieveOrganizationsResponse resp = (RetrieveOrganizationsResponse)dsp.Execute(req);

            foreach (var o in resp.Details)
            {
                //Show the friendly name of your CRM online org
                Console.WriteLine(o.FriendlyName);
            }

            Console.ReadKey(true);
        }
    }

05/11/2012

Define a Two way Connection between objects in CRM 2011


In brief, in MS dynamics CRM 2011 by using the “connect” feature we can bind any entity to any entity and define a one way or a two way relationship between records.
The concept is quite powerful! You can say we have invoices in CRM which already have a customer (contact) but we want to relate some of the invoices to our marketing people (system Users) to give commissions to the marketing users who referred a customer to us. In this example, I’ll show how to do it.

Define a Two way connection between invoices and system users

We want is to be able to “Connect” an invoice to a marketing person (User) and call the “Role” (relationship between Invoice and User) “Referral From”.
On the other hand, when we open the user information in CRM and click on the connections tab, we want to see a list of the invoices with the role of “Referral For” as role.
Here is how we can achieve this:


Define a Role (Relationship)

Navigate to Settings -> Business Management in CRM and click on “Connection Roles”
Click on “New” to create the connection relationship.
From Invoice we want to say “Referral From” and we want to use Invoice and User for record type just to say we need connections to be defined from invoice to users


The third step is the “Matching Connection Roles” where we can define the type of connection from User back to invoice. Select the sub grid and click on new on the ribbon to define a matching conection role




As you can see we called it “Referral From” this time and we select “User” and record type. Click on “Save” to store the information



Our two ways connection has been defined!

Test the connection

Open an invoice and let’s assume we want to define a user as “Referral From” for this invoice. Click on “Connect to another” from the ribbon:




And we assign a user (“BDE1 user” in this example as “Referral from”)


That’s it. Now if you open the “User” information and click on “Connections” on the left-hand side menu on the user form you will see the other way connection





16/10/2012

How to Use (REST) OData endpoint in CRM 2011


Simple Sample - How to use "ODATA" endpoint in CRM

Overview

There are two ways to write a client script to manipulate CRM data by code:
  • SOAP endpoint is recommended for retrieving metadata, assigning records and executing messages programmatically.
  • REST endpoint is recommended for creating, retrieving, updating and deleting, associating and disassociating the records.

 In this scenario, I will use REST (aka Organization data service - OData) to extract records out of CRM.

Simple Sample:

On load event of the Account form we want to show a message with the first name and country of primary contact of the selected account.
We are going to write a Java script which will be executed on load even of the Account form and we will use OData to retrieve the primary contact’s full name and Country

Solution

First we need to create a webreource and hook it to the “onLoad” event of the account, and then we need to write a code and use organization data service to access the primary contact of the account. For keeping everything simple, we will assume the primary contact is mandatory for an account on the time of creation (we won’t check if the primary contact is null)

Here are the actual steps (I assume you are at least at intermediate level in CRM and how to define webresources and add them to your form)

Add REST library and JSON from SDK

We are going to add JSON and SDK REST Javascript generic libraries from SDK to our CRM. These libraries are defined inside the SDK sample files and using them makes it very easy to write a readable code.
Let’s add those libraries. Create two new webresources and call them SDK_JQUERY and JSON.
For each library add the equivalent library from your SDK folder
“YOU SDK FOLDER \sdk\samplecode\js\restendpoint\javascriptrestdataoperations\javascriptrestdataoperations\scripts” and add sdk.rest.js
We need sdk.jquery and json2.js
Add REST SDK CRM 2011.jpg
Add Sdk Json.jpg

Create a webresource for our account form in CRM





Add the web resources we have created to account form libraries

Open the account form (the form below is not out of the box and is modified)


Click on form properties



Click on add under “Form libraries” and add the web resource we have created earlier to the form


Click on add under “Form libraries” again to add the two web resources from SDK library


In the "even handlers" section, click on add and bind the onLoad event handler


Double click on the form library you have just added and start adding your javascript:
function onLoad()
{
    
    alert("You are in the LoadContact function ");
    var primaryContactId =  Xrm.Page.data.entity.attributes.get('primarycontactid').getValue()[0];
    retrieveContact(primaryContactId.id);

}


function retrieveContact(contactId)
{
    SDK.REST.retrieveRecord(
     contactId,
     "Contact",
     null, null,
     function (contact)
     {
         alert("Retrieved the primary contact named \"" + contact.FullName + "\". This account was created on : \"" + contact.CreatedOn + "\".");
     },

     function ()
     {
         alert("Error occured.");
     }
   );
}


Using the SDK makes it really easy to use libraries to retrieve information or create and update field. Here is a useful like on how to use other methods in the library: http://technet.microsoft.com/en-us/library/gg309549.aspx#BKMK_CrmODataOperationsHTML