Monday 13 May 2013

CRM 2011 - JScript Error on Form Load (Errors On Page)

There are many reasons and causes of client side JScript errors, any line of code that has insufficient exception handling can result in an error message, for example when you are trying to call a function onload that doesn't exist. As you can see below, it's clear what the error is.
However there are scripting errors that are much harder to identify, which are displayed via the "Microsoft Dynamics CRM has encountered an error." dialog. Typically you will also get a "Errors on pageat the bottom left hand corner of your IE window:

Example Error
A recent example is where a colleague was experiencing errors after installing Rollup 12 and 13. The data being sent to Microsoft is displayed below:
Data that will be sent to Microsoft
  1. <CrmScriptErrorReport>
  2.   <ReportVersion>1.0</ReportVersion>
  3.   <ScriptErrorDetails>
  4.     <Message>Syntax error</Message>
  5.     <Line>306073745</Line>
  6.     <URL>/userdefined/edit.aspx?_gridType=4200&etc=4207&id=%7b998C4134-EAB3-E211-9A96-005056BC08B2%7d&pagemode=iframe&preloadcache=1368438373440&rskey=68511477</URL>
  7.     <PageURL>/userdefined/edit.aspx?_gridType=4200&etc=4207&id=%7b998C4134-EAB3-E211-9A96-005056BC08B2%7d&pagemode=iframe&preloadcache=1368438373440&rskey=68511477</PageURL>
  8.     <Function>anonymous(container,scriptContent,id){if(IsNull(container))container=this.get_headElement();var$v_0=container.ownerDocument.createElement("script");container.appendChild($v_0);!isNullOrEmptyString(id)&&$v_0.setAttribute("id",id);$v_0.setAttribute("type","</Function>
  9.     <CallStack>
  10.       <Function>anonymous(container,scriptContent,id){if(IsNull(container))container=this.get_headElement();var$v_0=container.ownerDocument.createElement("script");container.appendChild($v_0);!isNullOrEmptyString(id)&&$v_0.setAttribute("id",id);$v_0.setAttribute("type","text/javascript");$v_0.text=scriptContent}</Function>
  11.       <Function>anonymous(container,scriptFile){var$v_0=scriptFile.toString();if(this.$4V_1($v_0))return;var$v_1=this.fetchExternalFile($v_0);this.addIncludeInline(container,$v_1,$v_0)}</Function>
  12.       <Function>anonymous(uri,useInlineScripts,scriptLoaded){if(uri.get_path().toUpperCase()==="/_STATIC/_COMMON/SCRIPTS/GLOBAL.JS")uri=Mscrm.CrmUri.create("/_common/global.ashx");if(useInlineScripts)Mscrm.CrmHeader.get_scriptLoader().addIncludeExternalSync(null,uri);elseMscrm.CrmHeader.get_scriptLoader().addIncludeExternalCallback(null,uri,scriptLoaded)}</Function>
  13.       <Function>
  14.         anonymous($p0,$p1,$p2,$p3){Mscrm.CrmHeader.setScriptFile(Mscrm.CrmUri.create($p1),true);for(var$v_0=window,$v_1=$p0.split("."),$v_2=0;$v_2<$v_1.length;$v_2++)if($v_0)$v_0=$v_0=""[$v_1=""[$v_2=""]];if=""(!IsNull=""($v_0="")&&typeof$v_0===Mscrm.TypeNames.functionType){var$v_3=this.$CN_1($p2,$p3);return$v_0.apply(null,$v_3)}returnnull}
  15.       </Function>
  16.       <Function>anonymous($p0,$p1){var$v_0=this.$9w_1($p0.FunctionName,$p0.Library,$p0.Parameters,null);if(!IsNull($v_0)&&typeof$v_0===Mscrm.TypeNames.booleanType)return$v_0;elsereturn$p1}</Function>
  17.       <Function>anonymous($p0){if(IsNull($p0))returnfalse;var$v_0=$p0.DefaultValue;switch($p0.RuleType){case8:$v_0=this.$Cz_1($p0);break;case1:$v_0=this.$D2_1($p0);break;case7:$v_0=this.$D3_1($p0,$p0.DefaultValue);break;case4:$v_0=this.$D4_1($p0,$p0.DefaultValue);break;case16:$v_0=this.$D5_1($p0);break;case2:$v_0=this.$D6_1($p0);break;case10:$v_0=this.$D7_1($p0);break;case19:$v_0=this.$D8_1($p0,$p0.DefaultValue);break;case17:$v_0=this.$D9_1($p0);break;case12:$v_0=this.$DA_1($p0);break;case6:$v_0=this.$D1_1($p0,$p0.DefaultValue);break;case5:$v_0=this.$DB_1($p0,$p0.DefaultValue);break;case11:$v_0=this.$DC_1($p0);break;case3:$v_0=this.$DD_1($p0,$p0.DefaultValue);break}if(IsNull($v_0))$v_0=IsNull($p0.DefaultValue)?true:$p0.DefaultValue;if(!IsNull($p0.InvertResult)&&$p0.InvertResult)$v_0=!$v_0;return$v_0}</Function>
  18.       <Function>
  19.         anonymous($p0,$p1){var$v_0=this.getEnableRuleDefinition($p0,$p1);if(IsNull($v_0)||IsNull($v_0.Rules)||!$v_0.Rules.length)returntrue;for(var$v_1=true,$v_2=0;$v_1&&$v_2<$v_0.Rules.length;$v_2++)$v_1=$"v_1"&&this.$9v_1($v_0.Rules[$v_2]);return$v_1}
  20.       </Function>
  21.       <Function>
  22.         anonymous($p0,$p1){if(IsNull(Mscrm.RibbonCommands.enableRules))returntrue;var$v_0=this.getCommandDefinition($p0,$p1);if(IsNull($v_0))returntrue;var$v_1=$v_0.EnableRules;if(IsNull($v_1))returntrue;for(var$v_2=true,$v_3=0;$v_2&&$v_3<$v_1.length;$v_3++){var$v_4=$"v_1"[$v_3=""];if=""(IsNull=""($v_4="")||!$v_4.length="")continue;$v_2=$"v_2"&&this.$D0_1($v_4,$p1)}return$v_2}
  23.       </Function>
  24.       <Function>anonymous($p0){if(!this.$5T_1)returnfalse;var$v_0=this.parseCommandFromRibbon($p0),$v_1=this.$CH_1($v_0.command,$v_0.entityLogicalName);if($v_1&&!IsNull(this.$H_1.$5A_2[$p0]))$v_1=Mscrm.RibbonNavigationModel.shouldContextGroupBeShown($v_0,this.$H_1);elseif($v_1&&!IsNull(this.$H_1.$28_2[$p0]))$v_1=Mscrm.RibbonNavigationModel.shouldTabBeShown($p0,$v_0,this.$H_1);if(!IsNull(this.$H_1.$28_2[$p0]))this.$H_1.$28_2[$p0]=$v_1;return$v_1}</Function>
  25.     </CallStack>
  26.   </ScriptErrorDetails>
  27.   <ClientInformation>
  28.     <BrowserUserAgent>Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)</BrowserUserAgent>
  29.     <BrowserLanguage>en-us</BrowserLanguage>
  30.     <SystemLanguage>en-gb</SystemLanguage>
  31.     <UserLanguage>en-gb</UserLanguage>
  32.     <ScreenResolution>1280x1024</ScreenResolution>
  33.     <ClientName>Web</ClientName>
  34.     <ClientTime>2013-05-13T10:46:58</ClientTime>
  35.   </ClientInformation>
  36.   <ServerInformation>
  37.     <OrgLanguage>1033</OrgLanguage>
  38.     <OrgCulture>1033</OrgCulture>
  39.     <UserLanguage>1033</UserLanguage>
  40.     <UserCulture>1033</UserCulture>
  41.     <OrgID>{53547D16-0D2B-4BB4-A05D-3451C1C375D6}</OrgID>
  42.     <UserID>{54CDC85A-52B9-E211-891A-005056BC2521}</UserID>
  43.     <CRMVersion>5.0.9690.3448</CRMVersion>
  44.   </ServerInformation>
  45. </CrmScriptErrorReport>

The Issue
After analyzing the call stack, it became apparent that the issue was originating from the Ribbon, relating to enable rules which rely on JScript functions to determine if the users has access to that functionality.

It was pretty obvious after looking at the Ribbon XML, the issue was that their was a missing $webresource prefix from the library paths.

Missing $webresource
  1. <EnableRule Id="Imp.Form.Task.DataGroupButtons.EnableRule">
  2.   <CustomRule Library="KSR/Script/Common/AccessLibrary.js" FunctionName="KSR.Common.hasUserITSRole" InvertResult="true">
  3.   </CustomRule>
  4. </EnableRule>
  5. <EnableRule Id="Imp.Form.Task.RestrictAccess.EnableRule">
  6.   <CustomRule Library="KSR/Script/Common/AccessLibrary.js" FunctionName="KSR.Common.enableRestrictAccessButton">
  7.   </CustomRule>
  8. </EnableRule>

The Fix
With the $webresource
  1. <EnableRule Id="Imp.Form.Task.DataGroupButtons.EnableRule">
  2.   <CustomRule Library="$webresource:KSR/Script/Common/AccessLibrary.js" FunctionName="KSR.Common.hasUserITSRole" InvertResult="true">
  3.   </CustomRule>
  4. </EnableRule>
  5. <EnableRule Id="Imp.Form.Task.RestrictAccess.EnableRule">
  6.   <CustomRule Library="$webresource:KSR/Script/Common/AccessLibrary.js" FunctionName="KSR.Common.enableRestrictAccessButton">
  7.   </CustomRule>
  8. </EnableRule>

Hope this helps :)

Thursday 9 May 2013

How to get OptionSet values using SQL?

Obtaining a list of option values for a MS CRM 2011 OptionSet is pretty simple, especially if you plan to do this via the CRM Web service API. However a requirement may arise where you may want to do this using direct SQL against the Organization database.

Example Background

By default on the account entity there are several address fields, and one in particular is the Address Type picklist which is used to categorize the type of address stored for this account. Using this field as an example, the following SQL Query can be used to obtain a list of all options available to that field:


SQL Statement
  1. SELECT
  2. EV.LogicalName as Entity,
  3. ALV.Name as Attribute,
  4. LLV.Label,
  5. APV.Value
  6. FROM LocalizedLabelView as LLV
  7.     INNER JOIN AttributePicklistValueView as APV ON LLV.ObjectId = APV.AttributePicklistValueId
  8.     INNER JOIN OptionSetView as O ON APV.OptionSetId = O.OptionSetId
  9.     INNER JOIN AttributeLogicalView as ALV ON O.OptionSetId = ALV.OptionSetID
  10.     INNER JOIN EntityView as EV ON ALV.EntityId = EV.EntityId
  11. WHERE
  12.     ALV.Name like '%address1_addresstypecode%' AND EV.LogicalName = 'account'
  13. ORDER BY EV.LogicalName, ALV.Name, APV.Value

SQL Results


Enjoy :)

Action Microsoft.Crm.Setup.Common.Analyzer +CollectAction failed. Fatal error during installation

When installing the Srs Data Connection (Microsoft Dynamics CRM Reporting Extensions), you may have experienced the following error: ...