Friday, November 27, 2009

MS CRM 4.0 CSS Stylesheet Template is released!

Microsoft released CRM Sdk v 4.0.11 on Nov 24, 2009. Here is a list of updated features at a glance:
The package includes a visual style guide you can use to make your customizations fit in smoothly, and a style sheet you can use as a basis for your work. There are also tools and helper code provided in this package. Look for regular updates to this SDK!

Download Link:
CRM Sdk v 4.0.11
MS CRM 4.0 CSS Stylesheet

XrmVisioER: CRM/xRM ER Diagram Generator Revised Version

Last week, my colleague said XrmVisioER diagram generator takes too long to retrieve entity information at log-in process. When he tried the program for first time, he even though it was not working :) I also noticed that its took around 3 mins+ to retrieve meta data information from remote server. This morning, I decided to review my program again and did necessary changes.

Here is the list of updated features:
  • Reduce processing time at application log-in process
  • Apply caching concepts on meta data retrieval process
  • Diagram pages will be shown as display name of an entity
  • Provide user friendly information on screen while generating diagrams






Configuration:
Connection: Cable 8 mbps
Server: Remote Hosted Server, Win 2003, 4GB RAM, VMWARE
Client: WinXP, 2GB RAM,  Core 2 Duo 1.8 GHz

Testing Scenario:
Drawing 1 entity: takes 1 min+
Drawing 3 entities: takes 1 min 28 sec
Drawing 280 entities: takes 15 mins+ (avg of 3.4 sec/entity)

Download Link:
XrmVisioER - CRM/xRM ER Diagram Generator (Application)
XrmVisioER - CRM/xRM ER Diagram Generator (Source Code)

Reference:
XrmVisioER - Metadata Diagram Generator
Power User Tips: The CRM 4.0 Metadata Cache

----------------------------------------------------
Updated on 16th Dec 2009:
  • Add re-size feature to entity diagram
  • Remove relationship attribute name from entity diagram
  • Add an option to draw all entities in one page

Sunday, November 22, 2009

xRM at Microsoft PDC09




Microsoft PDC09 conference was held in LA this week. They discussed about CRM 5.0 and xRM application development there. Below is the list of videos and presentation slides I found on PDC website.
  1. Developing xRM Application using Windows Azure 
  2. Managing the Solution Lifecycle for xRM Applications
  3. Building a .NET Business Application in 60 mins with xRM and Sharepoint
You can find out more information at Microsoft PDC09 Videos

CRM 5.0 At A Glance

Monday, November 16, 2009

SQL Server: Failed to pause full-text catalog for backup

Last week, my users complaint that they cannot perform regular backup on SQL Server using their backup software. I tried to investigate on backup process and found the error message stated below:



After searching through Google for a while, I found the source of problem which is related to SQL Server FullText Search Service. By right, this service must run under Local System account. But, their service is running under NT Authority/Network Service.

Reason: When SQL server is performing backup process, they tried to pause FullText Search service. If this service is not running under Local System account, there is no way they can pause this service and error message stated above will be appeared.

Caution: If you want to perform database restore process in MS CRM databases, you have to stop Microsoft CRM Asynchronous Service before you start your restore process.

Saturday, November 14, 2009

Local SMTP Virtual Server Configuration for CRM Outgoing Emails

If you want to use local SMTP virtual server for outgoing emails in CRM application, please review following document for installation and configuration guide-line.

This document consists of FOUR sections:
  1. Installing and configuration local SMTP service
  2. Configuration CRM email router
  3. Configuring outgoing email access for CRM users
  4. Testing outgoing email
Download Link

XRM Notebook has beed listed as a Member Blog in XRM Virtual User Group

Today, my technical blog, XRM Notebook, has been listed as a member blog in XRM Virtual User Group. Thanks to Julie Yack who gives me a chance to participate and contribute my knowledge in our XRM Community.

Wednesday, November 11, 2009

Trace Errors on CRM Workflows and Asynchronous Plug-ins

All Workflows and (async) plug-ins are running under CRM Asynchronous service. It is difficult to trace an error message when those workflows and asynchronous plug-ins are not working properly.

Here is the solution to trace errors:
  • Go to Advanced Find, choose System Job entity, and set the filter parameter as follow:

  • Click Edit Columns, and add TWO more columns called Error Code and Message.

  • Click Find to view result

Tuesday, November 10, 2009

CRM: SecLib::CheckPrivilege failed.

SecLib::CheckPrivilege failed. Returned hr = -2147220960,
User: 38327113-f014-dd11-8a77-0004e240fb2e,
PrivilegeId: ea8e9601-500e-4bd7-be73-022f3269e5b6

A CRM application may encounter privilege error in some sdk operations (i.e.; CURD). It will be a time consuming task for a developer to trace such kind of error if they don't know how to check it. They have to go through each and every entity to identify whether the defined user roles have correct privileges or not.

The first and easiest way is here.
  • Take PrivilegeId from above error message. (e.g.; ea8e9601-500e-4bd7-be73-022f3269e5b6)
  • Run following query to retrieve privilege name which was not set correctly in user role

  • Give correct privilege (e.g.; Read Access to dvm_girorejectreason entity) to required Role assigned to the specific user (e.g.; 38327113-f014-dd11-8a77-0004e240fb2e). If you do not know how to check the user in SQL server please let me know.

Caution: If you cannot find the PrivilegId in error message, please check whether specified use has a role assigned to it. Most likely thing is there is no user role assign to that user.

Sunday, November 8, 2009

XRM Auto-Number Plugin (Online)

One of the most frequently asked features in xRM development is Auto-number @ Running Number generation process. Microsoft supports auto number generation for a few predefined entities like Contracts, Case, Invoice, Order etc.

Since I have been working in donation and clinical system projects, I found that most of our users request such feature in receipt number generation, reference number generation and document number generation processes. It is a quite common feature that they request.

There are a few ready-made CRM plug-ins out there. But most of them are only focus for numeric data type running numbers and cannot support for padding and/or auto number reset features. So, I decided to do it on my own way.

Let's take a look on the features of my Auto-number Plug-in:
  • This plug-in is supported only for server deployment and create message of any custom entity. 
  • Offline client does not need to register this plug-in since the number will auto populate when they sync back their offline data to CRM server.
  • Data type of running number attribute in custom entity can be either string (nvarchar) or integer data type. The rest is not supported.
  • You can specify auto reset number and padding format of running number in configuration setup.  Please check the screens below.
  • Prefix and Suffix values can be either fixed values or datetime ori ented values. Plugin will automatically parsed the value into date time format if  you provide datetime format in curly brackets:, for example {MM}-{yy} will be parsed into ’11-09’


Download Link:
Feel free to use this application.
Either leave comment or email me if you want to know further information.

Saturday, November 7, 2009

Configuration for Offline Client Plugins

If you received an error "Unable to load plug-in assembly." when triggering the plug-in under offline client mode, please configure the following steps:

  • Open Plug-in Registration Tool
  • Copy Public Key Token value under Assembly Information Section



  • Open registry in offline client computer
  • Create sub key folder with Public Key Token value under HKCU\Software\Microsoft\MSCRM Client\AllowList folder (E.g. 43820d73570614d5 here in current scenario)


Make sure you configure your plug-in executing context as “Calling User”. Please take note that Offline client application can be run under single user who is register to that computer.



For faster and easier installation, copy following quoted lines into a text file and change file extension to .reg file. You need to replace yellow color text with relevant values. Double click and install registry values on Offline client laptops. You can also put multiple public key tokens in one registry file.
 
Windows Registry Editor Version 5.00

;(Plugin) YourPluginNamespace.PluginClassName
[HKEY_CURRENT_USER\Software\Microsoft\MSCRMClient\AllowList\PublicKeyToken]

;(Plugin) YourPluginNamespace.PluginClassName
[HKEY_CURRENT_USER\Software\Microsoft\MSCRMClient\AllowList\PublicKeyToken]

Download Link:
Sample File

Wednesday, November 4, 2009

XRM Capitalize Attribute Plugin (Online/Offline)

Our users want to capitalize some of the attribute values from CRM entities when they save the data. The most frequently asked attributes that they want to capitalize are fullname, first name, last name, account name, and address information, etc.

You may think that it is easy to change string format through java script functions. But, if you have some external applications and CRM extension included in your project, it will be very hard to control the consistent of your application code. So, I planned to write a generic plug-in which is easy to configure and provide a variety of  capitalized functions through central configuration setup. (The idea of configuration setup implementation comes from  a33ik. Please refer my post for more detail)












String Capitalize Effects:
  • All Caps. Example; THUTA HLAING
  • Small Caps: Example; thuta hlaing
  • Word Cap: Example; Thuta Hlaing
  • First Char Cap: Example; Thuta hlaing

Download Link:
Feel free to use this application.
Either leave comment or email me if you want to know further information.

Sunday, November 1, 2009

How to retrieve entity and its related attributes in CRM Form










I was working with MS CRM plug-ins for half a year already. When we worked on reusable plug-ins, we needed a setup entity to store some configuration setting that is required in plug-in execution. Most of the time, we need to store THREE configuration values: entity, their related attributes and plug-in related settings.
Luckily, I found out a good article on Internet which was written by a33ik. After playing around with his program for a while, I realize that this is the idea that I am looking for. I want to apply this idea in my reusable plug-ins. Thanks  to a33ik for sharing his idea.

As usual, I changed a little bit on his original idea since my scenario did not need to create all related attributes in child table setup. Moreover, I was worry on performance of CRM when we query through Parent - Child tables to retrieve setup information, and when we run plug-in to extract all related attributes and create unnecessary records.
Another thing is about consistency. If user changed customization of attributes (for example; display name) on CRM, setup table may not be updated automatically.So, lesser information storgae will help us reducing consistency issues. I also add one javascript function to auto populate attribute information and update when user saved the configuration record. For your convenience, here is my javscript code sample:

entityOnChange = function ()
{
crmForm.all.psx_entityname.DataValue = document.getElementById('psx_schemaname').options[document.getElementById('psx_schemaname').selectedIndex].innerText;

var schemaName = document.getElementById('psx_schemaname').options[document.getElementById('psx_schemaname').selectedIndex].getAttribute('schemaName');

var request = "" +
"<soap:envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
" <soap:body>" +  
"     <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
"         <request xsi:type="RetrieveEntityRequest">" +
"             <metadataid>00000000-0000-0000-0000-000000000000</metadataid>" +
"             <entityitems>IncludeAttributes</entityitems>" +
"             <logicalname>" + schemaName + "</logicalname>" +
"             <retrieveasifpublished>true</retrieveasifpublished>" +
"         </request>" +
"     </execute>" +
" </soap:body>" + 
"</soap:envelope>";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/MetadataService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", request.length);
xmlHttpRequest.send(request);

var result = xmlHttpRequest.responseXML;
var schemaNames = result.selectNodes("//EntityMetadata/Attributes/Attribute");
ConvertAttributeToPicklist('psx_attributename', schemaNames);
}

attribOnChange = function ()
{
crmForm.all.psx_displayname.DataValue = document.getElementById('psx_attributename').options[document.getElementById('psx_attributename').selectedIndex].innerText;
}

function ConvertEntityToPicklist(fieldName, dataItems)
{
var defaultValue = crmForm.all[fieldName].DataValue;
var table = crmForm.all[fieldName + "_d"]; 
var select = "<select class="ms-crm-SelectBox" defaultselected="" id="" + fieldName + "" name="" + fieldName + "" onchange="javascript:entityOnChange();" req="0" tabindex="1170">      <option ).text="" +="" ;="" logicalname="" value="" + dataItems[i].selectSingleNode(">            select += "schemaName='"+ dataItems[i].selectSingleNode('LogicalName').text+"'";                        if (dataItems[i].selectSingleNode('LogicalName').text == defaultValue)             {                select += " SELECTED";                defaultValueFound = true;            }                        select += ">" + dataItems[i].selectSingleNode('DisplayName/LocLabels/LocLabel/Label').text + "</option>        <option selected="selected" value="" + defaultValue + "">" + defaultValue + "</option> </select>";

table.innerHTML = select; 
entityOnChange();
}

function ConvertAttributeToPicklist(fieldName, dataItems)
{
var defaultValue = crmForm.ObjectId != null ? crmForm.all[fieldName].DataValue: null;
var table = crmForm.all[fieldName + "_d"]; 

var select = "<select class="ms-crm-SelectBox" defaultselected="" id="" + fieldName + "" name="" + fieldName + "" onchange="javascript:attribOnChange();" req="0" tabindex="1170">       <option ).text="" +="" ;="" logicalname="" value="" + dataItems[i].selectSingleNode(">            select += "schemaName='"+ dataItems[i].selectSingleNode('LogicalName').text+"'";                        if (dataItems[i].selectSingleNode('LogicalName').text == defaultValue)             {                select += " SELECTED";                defaultValueFound = true;            }            select += ">" + dataItems[i].selectSingleNode('DisplayName/LocLabels/LocLabel/Label').text + "</option>        <option selected="selected" value="" + defaultValue + "">" + defaultValue + "</option> </select>";

table.innerHTML = select; 
attribOnChange();
}

var request = "" +
"<soap:envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
"  <soap:body>" +  
"    <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
"      <request xsi:type="\"RetrieveAllEntitiesRequest\"">" +
"        <retrieveasifpublished>true</retrieveasifpublished>" +
"        <metadataitems>EntitiesOnly</metadataitems>" +
"      </request>" +
"    </execute>" +
"  </soap:body>" + 
"</soap:envelope>";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/MetadataService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", request.length);
xmlHttpRequest.send(request);

var result = xmlHttpRequest.responseXML;
var schemaNames = result.selectNodes("//CrmMetadata/CrmMetadata");

ConvertEntityToPicklist('psx_schemaname', schemaNames);  
crmForm.all.psx_entityname.ForceSubmit = true;

document.getElementById('psx_entityname').style.visibility = 'hidden';
document.getElementById('psx_entityname_d').style.visibility = 'hidden';
document.getElementById('psx_entityname_c').style.visibility = 'hidden';
crmForm.all.psx_displayname.ForceSubmit = true;
document.getElementById('psx_displayname').style.visibility = 'hidden';
document.getElementById('psx_displayname_d').style.visibility = 'hidden';
document.getElementById('psx_displayname_c').style.visibility = 'hidden';
 
if (crmForm.ObjectId != null)
{    
document.getElementById('psx_schemaname_d').disabled = true;
document.getElementById('psx_attributename_d').disabled = true;
} 

Download: 
Customization File

Feel free to use this application.
Either leave comment or email me if you want to know further information.

Reference:
Field Security Level With Own Hands