Tuesday, June 22, 2010

Clone Record in CRM using CrmServiceToolkit (JavaScript)

A few weeks ago, one of our customers requested record cloning features in some of our customized entities. I tried to look for this feature through internet and found out a lot of interesting articles stating different ways of cloning records.

Below is the list of articles I found out for your reference:
  1. Clone Records Without Code
  2. Clone Records Using Workflow
  3. Cloning Records In Microsoft CRM 4.0 Using AJAX Controls
Among them, I decided to use ASP.NET way. I download the source code, modified it a bit and used in our project. After testing for a few days, I noticed about five or six seconds delay to load an asp.net page when I click "Clone Record" button for the first time.

I discussed about this issue with one my colleagues and he suggested me to use CRM Web Service Toolkit (JS) framework to clone the record. It is not very easy to use, but it helps us a lot to solve our performance issues and reduce steps in deployment. We are using this toolkit to retrieve data from CRM directly instead of writing our own asmx web services applications. Of course, you need to reference CrmServiceToolkit in your JavaScript deployment. Thanks to Daniel Cai for his research, great effort and generous contribution to our CRM community.

Below is my JavaScript source code:

 
onCloneRecordClick = function()
{
    try
    {
        if(confirm('Do you want to create a duplicate record?'))
        {
            // Create Clone Record and Retrieve Primary Key
            var _id = makeClone(crmForm.ObjectTypeName, crmForm.ObjectId);
           
            // Open Newly Created Record in CRM

            if(confirm('Duplicate record created successfully.\nDo you want to open it?'))
            {
                var _url = getFormURL(crmForm.ObjectTypeName, _id);
                window.open(_url, "_self");
            }
        }
    }
    catch(ex)
    {
        showError(ex.description);
    }
} 

// Create Clone Record
makeClone = function(entityName, objId)
{
    var attribName = crmForm.ObjectTypeName + "id";
    var fetchXML =     "" +
                    "" +
                    "";        
    var oSource = CrmServiceToolkit.Fetch(fetchXML);        
    
    // Create Clone Record
    var oClone = new CrmServiceToolkit.BusinessEntity(entityName);        
    for ( var p in oSource[0].attributes)
        if(p != attribName)
            oClone.attributes[p] = oSource[0].attributes[p].value;
        
    var id = CrmServiceToolkit.Create(oClone);
    return id;
}

// Retrieve URL to Open CRM Form
getFormURL = function(entityName, objId)
{
    var path = "../../../userdefined/edit.aspx?id=" + objId + "&etn=" + entityName;
    return path;
}

// Show Error Message 
showError = function(message)
{
    attachOnChangeAllControls();

    var notificationsArea = document.getElementById('Notifications');
    
    if (notificationsArea == null)
    {
        alert(message);
         return;
    }
    notificationsArea.title = '0';
    var notificationHTML = '









' + message + '
';     notificationsArea.innerHTML += notificationHTML;     notificationsArea.style.display = 'block'; } 

Explanation:
(added on 2nd Sept 2010)

How to use CrmServiceToolkit in CRM?
1. Download CRM Service Toolkit from codeplex
2. Extract zip file and place CrmServiceToolkit.min.js and qunit.js files under ISV folder
3. Use loadscript() function to load CrmServiceToolkit file to CRM at Form Load Event (Please refer to henrycordes' blog) This is not recommended by Microsoft.
4. Use above CloneRecord code in your CRM Form.


Reference:

Thursday, June 3, 2010

FilteredView and ASP.NET Impersonation

A few days ago, we re-deployed a CRM project in staging server for maintenance purpose. We did normal re-deployment processes such as backup live database, imported it into staging server, run deployment manger to re-configure the settings, re-deployed extension pages, etc.

We tested CRM application and it was working fine. Yesterday, we noticed all extension pages (aspx) using  "Filtered Views" to retrieve data from SQL Server were not working properly. We are using "Filtered Views" in stored procedures to retrieve data from SQL Server. 

Below is the list of steps I did for troubleshooting:
  1. The login user was a member of System Administrator Role. So, it could not be an Access Rights issue.
  2. I run one stored procedure under login user's credential (using EXECUTE AS command) and it was working properly. I can retrieve the data. So, impersonation process was working fine and it can be either configuration error or impersonation cannot go through from website to SQL Server.
  3. I checked all registry values, application settings, IIS configurations, IE settings and system configuration data in MSCRM_CONFIG and CRM database respectively. All settings were correct.
  4. Finally, I added <identity impersonate="true" /> in web.config file of our extension project. Then, system prompted there was another impersonation setting already configured in that file. I searched the value and found that impersonation was set to false.
This happened because one of my colleagues accidentally configured impersonation setting through IIS's website properties. This is not a big issue, but it took me about one hour to resolve this. So, I blog this post to save your time and save my time in future if I forgot it. :-)

Reference: