Friday 29 March 2013

Managed VS Un managed Solution in MSCRM 2011

Think of unmanaged solutions as source code and think of managed solutions as compiled, versioned and signed assemblies.
How to delete any of its entities, attributes, relationships, reports and Option Sets from Managed Solution  in MSCRM 2011:


 Hide instead of delete. The easiest solution is to simply create the new attribute with the correct data type and completely hide the old attribute from all views, forms, reports, etc. In many cases, deleting an attribute in production is unacceptable because of data loss so this alternative is the safest and most conservative as you get to keep the old data. The disadvantage is that you will have useless columns in your database and the old attribute will continue to appear in Advanced Find.


2. Use a holding solution to delete any component from your deployed managed solution. This is my favourite approach as it has the advantage of completely deleting from the system the unwanted components without losing any data. This is how it works: Assume you have a solution XXX which contains a custom entity and one of the attributes is of type “Single Line of Text” but you want to change it to “Multiple Lines of Text”. In your target environment you should have solution XXX as managed and in your development environment you should have solution XXX as unmanaged.

  1. In your development environment create a new solution “XXX_holding”. The publisher must be the same as the publisher of your XXX solution.
  2. Add all the components of the XXX solution to your XXX_holding solution*.
  3. Export XXX_holding as managed.
  4. Import XXX_holding to your target environment.
  5. Delete XXX solution from your target environment. No data is lost because all the customizations remain in the holding solution.
  6. In your development environment delete the attribute (you will need to adjust views, forms, etc.).
  7. Export XXX as managed.
  8. Import XXX to your target environment
  9. Delete XXX_holding from your target environment. The attribute will now be deleted from all environments. There is no data loss except for the data that was saved in the old attribute which was deleted.
  10. Now that the attribute is deleted, if you want the attribute back but with a different data type you just need to re-create it in dev and promote the solution to your target environment.
* Note: You can avoid steps 1-3 if you simply open your XXX solution zip file and in the solution.xml file you update the solution unique name to “XXX_holding”. This way you guarantee that you have all the components of XXX also in XXX_holding.


3. Uninstall and re-install solution. If you absolutely need to wipe out the old attribute from the system, you could also uninstall the entire managed solution, make the appropriate changes in your development environment and then re-deploy a clean and correct version of your managed solution. The big disadvantage here is that you will lose your data if it relies on the customizations of your solution, which is usually unacceptable unless you have no data to retain or the data is not important.


4. Use unmanaged solutions instead of managed solutions. While it is true that with unmanaged solutions it is simpler to manually delete any component, it is also true that deploying unmanaged solutions to a production environment has multiple disadvantages and is not a good practice in my perspective. It might also be too late for you to switch to unmanaged solutions.

Tuesday 26 March 2013

MSCRM  Fetch XML 5000 Records Limitation:


Have you ever tried to write a code which will get you all records from a specific entity? It's harder then you think it is! Everybody who is a bit aware of the CRM SDK thinks it should be a fetch statement like this:

<fetch mapping='logical'><entity name='account'><attribute name='accountid'/></entity>

WRONG!
This would only give you the first 5000 records in the database! It is written down in the SDK with small letters, but it could drive you crazy..

There are two solutions for this issue.
1) Add a registery setting to specify not to implement MaxRowsPerPage
2) Modify the fetch statement and merge several results

Here are the details for each solution
1st solution
Search in the SDK for the word "TurnOffFetchThrottling". You should add this as DWORD registery setting to HKLM\Software\Microsoft\MSCRM. Set the value to 1. You will now not have the 5000 records limit.

2nd solution
Modify your fetch statement to include paging and count numbers. Store all the data in an DataSet and perform that series of code over and over again as long as there is data coming.

Here's the script you should use to get all accountid's (for clarity and the ease of use I have added a function called "FetchDataSet").


private DataSet FetchAllAccountIds(){
int i=1;
bool bFinished = false;
DataSet dsAllData = new DataSet();
while (bFinished == false)
{
StringBuilder sbFetch = new StringBuilder();
sbFetch.AppendFormat("<fetch mapping='logical' page='{0}' count='5000'>", i);
sbFetch.Append("<entity name='account'>");
sbFetch.Append("<attribute name='accountid'/>");
sbFetch.Append("<attribute name='new_12_accountid'/>");
sbFetch.Append("</entity>");
sbFetch.Append("</fetch>");
DataSet dsTempResult = FetchDataSet(sbFetch.ToString());
dsAllData.Merge(dsTempResult);
if (dsTempResult.Tables[0].Rows[0]["morerecords"].ToString() == "0")
{
bFinished = true;
}
else
{
i++;
}
}
return dsAllData;
}

private DataSet FetchDataSet(string fetchXml)
{
string strResult = service.Fetch(fetchXml);
DataSet ds = new DataSet();
System.IO.StringReader reader = new System.IO.StringReader(strResult);
ds.ReadXml(reader);
return ds;
}


Friday 22 March 2013

How to Achieve  the creation  of  activity records for each marketing list member  on Addition of marketing list to campaign in MSCRM  2011 Custom workflow:


1. First we have to create a text field ( to have latest marketing list guid which is associated recently ) which should be hidden on campaign  
2.  Update this field on  association of marketing list to campaign (Additem  plugin Message on campaign entity).
3. Write custom work flow on update of this campaign record hidden field   which will fetch the associated marketing list from campaign record based on  hidden field text (which is recently added marketing list guid) , then list members and create custom record for each.



Retrieving Marketing List members  in MSCRM  Statsic VS Dynamic:

Firstly, let’s identify the main difference between a static and dynamic Marketing List. A static Marketing List allows you to use Lookup or Advanced Find to add or remove members from the list. However, this is a manual process.
A dynamic Marketing List allows you to setup parameters to control which records will be added or removed from a list. For example, you can setup your dynamic Marketing List to include all Contacts who live in Auckland. Whenever a new Contact is created and has their City set to “Auckland”, CRM will automatically add them to the Marketing List.
The next important difference to note is the way in which Marketing List members are stored in the CRM database. Like Dynamics CRM 4.0, information regarding members belonging to a static Marketing List is stored in two tables. These are:
List – This table stores information about the Marketing List itself.
List Member – This is an intersect table which links a Contact, Account, or Lead to a particular Marketing List.
 Retrieving Marketing List Members in CRM 2011
For example, if we have a Contact in a static Marketing List, the intersect table will store the ContactId and the ListId to associate both records together.
Let’s contrast this with a dynamic Marketing List which doesn’t use the List or List Member tables at all. Instead, the Listtable stores a field called Query which stores a FetchXML query string to determine the Marketing List members. Carrying on with the example above, we would have a FetchXML representation of “all Contacts who live in Auckland”. When the Marketing List is opened in CRM and a user clicks on Marketing List Members, CRM will run the FetchXML query at runtime and display the results to the user.
 Retrieving Marketing List Members in CRM 2011

Code to get the execution entity id , name  in MSCRM custom Workflow:


IWorkflowContext contexto = context.GetExtension<IWorkflowContext>();
String entityName = contexto.PrimaryEntityName;
Guid entityId = contexto.PrimaryEntityId;
Activity Feed @ MSCRM:




1) Creating Microsoft CRM 2011 Activity Feed Auto Posts with Workflow

2) Activity Feeds Report

3)   CRM 2011 – Activity Feed Article List



Introduction to activity feeds by Richard Knudson

http://www.dynamicscrmtrickbag.com/2011/11/13/activity_feeds/

Activity feed rules

http://gotchahunter.net/2011/11/activity-feeds-rules-in-dynamics-crm-2011/

Activity feeds

http://gtcrm.wordpress.com/2011/11/16/activity-feeds-in-microsoft-crm-2011/

How to do mentions in activity feeds

http://blogs.msdn.com/b/crm/archive/2011/10/31/how-to-do-mentions-with-activity-feeds.aspx

Sample code for activity feeds

http://msdn.microsoft.com/en-us/library/hh547450.aspx

working with the SDK and activity feeds

http://blogs.msdn.com/b/crm/archive/2011/10/31/working-with-activity-feed-using-microsoft-crm-sdk1.aspx

How to create a post with mentions using a workflow

http://blogs.msdn.com/b/crm/archive/2011/11/07/how-to-create-a-post-with-mentions-using-workflow.aspx

following and unfollowing records in CRM

http://blogs.msdn.com/b/crm/archive/2011/10/27/following-and-unfollowing-records-in-crm.aspx

How to add a record to the wall

http://blogs.msdn.com/b/crm/archive/2011/11/09/how-to-add-a-record-wall-to-a-form.aspx

5) How to Create a Post with Mentions using Workflow?

http://blogs.msdn.com/b/crm/archive/2011/11/07/how-to-create-a-post-with-mentions-using-workflow.aspx

6) Microsoft Dynamic CRM 2011 Activity Feed Part 2 – Working with Activity Feeds - http://www.powerobjects.com/blog/2011/11/07/microsoft-dynamic-crm-2011-activity-feed-part-2-working-with-activity-feeds/

7) Check out the new Activity feeds in Dynamics CRM 2011

http://www.magnetismsolutions.co.nz/blog/bina/11-11-25/Check_out_the_new_Activity_feeds_in_Dynamics_CRM_2011.aspx

8)  Introduction to the Activity Feeds Solution
http://rc.crm.dynamics.com/rc/2011/en-us/on-prem/5.0/start_with_activity_feeds.aspx



9) Microsoft Dynamics CRM 2011 Activity Feeds – Configuring Custom Entities
http://info.profad.com/bid/78820/Microsoft-Dynamics-CRM-2011-Activity-Feeds-Configuring-Custom-Entities

10) Microsoft Dynamics CRM 2011 Activity Feed, Part 1 – Getting Started

http://www.linkedin.com/groups/Microsoft-Dynamics-CRM-2011-Activity-114154.S.83653659?view=&gid=114154&type=member&item=83653659&trk=eml-anet_dig-b_nd-pst_ttle-cn

11) Best Practices for Activity Reporting In Microsoft Dynamics CRM 2011

http://blog.customereffective.com/blog/2011/12/best-practices-for-activity-reporting-in-microsoft-dynamics-crm-2011.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+CustomerEffectiveBlog+%28Customer+Effective+Blog%29

12) Light “spackling” for your Activity Feed walls

http://blog.sonomapartners.com/2011/12/light-spackling-for-your-activity-feed-walls.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+typepad%2Fsonoma+%28Sonoma+Partners+Microsoft+CRM+Blog%29

13)  CRM 2011 Activity Posts via Workflow

http://stevengevers.wordpress.com/2012/03/22/crm-2011-activity-posts-via-workflow/


C# code to execute custom workflow in MSCRM 2011:


ExecuteWorkflowRequest request = new ExecuteWorkflowRequest()
{
    WorkflowId = _workflowId,
    EntityId = _leadId
};
Console.Write("Created ExecuteWorkflow request, ");

// Execute the workflow.
ExecuteWorkflowResponse response =
    (ExecuteWorkflowResponse)_serviceProxy.Execute(request);

code to retrieve the Marketing lIst memebers in MSCRM 2011:


Query Expression: we will fetch 5000 records first then next 5000 ...continued... more useful in custom workflows

 ArrayList memberGuids = new ArrayList();                        
                        PagingInfo pageInfo = new PagingInfo();
                         pageInfo.Count = 5000;
                         pageInfo.PageNumber = 1;

                        QueryByAttribute query = new QueryByAttribute("listmember");
                         // pass the guid of the Static marketing list
                        query.AddAttributeValue("listid", marketingListId);
                         query.ColumnSet = new ColumnSet(true);
                         EntityCollection entityCollection = service.RetrieveMultiple(query);

                        foreach (Entity entity in entityCollection.Entities)
                         {
                         memberGuids.Add(((EntityReference) entity.Attributes["entityid"]).Id);
                         }

                        // if list contains more than 5000 records
                         while (entityCollection.MoreRecords)
                         {
                         query.PageInfo.PageNumber += 1;
                         query.PageInfo.PagingCookie = entityCollection.PagingCookie;
                         entityCollection = service.RetrieveMultiple(query);

                        foreach (Entity entity in entityCollection.Entities)
                         {
                         memberGuids.Add(((EntityReference)entity.Attributes["entityid"]).Id);
                         }
                         }











Fetch XML:

string ListMembersfetchXml = @"<fetch version=""1.0"" output-format=""xml-platform"" mapping=""logical"" distinct=""false"">
                                                                      <entity name=""listmember"">
                                                                            <attribute name=""entityid"" />
                                                                            <attribute name=""entitytype"" />                                                      
                                                                            <filter type=""and"">
                                                                              <condition attribute=""listid"" operator=""eq""  value=""" + new Guid(marketingListId) + @""" />
                                                                            </filter>
                                                                      </entity>
                                                                     </fetch>";

                                                EntityCollection listMemberResult = service.RetrieveMultiple(new FetchExpression(ListMembersfetchXml));






Javascript code: BY NIshanth Rana

// call this function and pass the id of the static marketing list to it
 function GetAllMembers(listGuid)
 {

 _oService='';
 _sOrgName = "";
 memberArray = new Array();
 morePages = 'true';
 pageNumber = 1;
 pageCookie = '';
 recordGuid='';
 XMLHTTPSUCCESS = 200;
 XMLHTTPREADY = 4;

 context = typeof (Xrm) == "undefined" ? GetGlobalContext() : Xrm.Page.context;
 var _sServerUrl = context.getServerUrl();
 if (_sServerUrl.match(/\/$/)) {
 _sServerUrl= _sServerUrl.substring(0, serverUrl.length - 1);
 }

 GetMarketingListMembers(listGuid);

}

function GetMarketingListMembers(listGuid) {

 fetchOnLoad(pageNumber, pageCookie, listGuid);

for (var i = 0; i < memberArray.length; i++) {

alert(memberArray[i]);
 // Iterates over numeric indexes from 0 to 5, as everyone expects
 }
 }

function fetchOnLoad(pageNumber, pageCookie, listGuid) {

 recordGuid = listGuid;

var sFetch = "<fetch mapping='logical' page='" + pageNumber + "' count='5000' paging-cookie='" + pageCookie + "' version='1.0'>" +
 "<entity name='listmember'>" +
 "<attribute name='entityid' />" +
 "<filter>" +
 "<condition attribute='listid' operator='eq' value='" + recordGuid + "' />" +
 "</filter>" +
 "</entity>" +
 "</fetch>";

_oService = new FetchUtil(_sOrgName, _sServerUrl);
 _oService.Fetch(sFetch, myCallBack);

}
 function myCallBack(results) {

// add all the member in the array

for (i in results) {
 memberArray.push(results[i].attributes.entityid.guid);
 }

if (morePages == 'true') {
 fetchOnLoad(pageNumber, pageCookie, recordGuid);
 }

}

function FetchUtil(sOrg, sServer) {
 this.org = sOrg;
 this.server = sServer;
 if (sOrg == null) {
 if (typeof(ORG_UNIQUE_NAME) != "undefined") {
 this.org = ORG_UNIQUE_NAME;
 }
 }
 if (sServer == null) {
 this.server = window.location.protocol + "//" + window.location.host;
 }
 }

FetchUtil.prototype._ExecuteRequest = function(sXml, sMessage, fInternalCallback, fUserCallback) {
 var xmlhttp = new XMLHttpRequest();
 xmlhttp.open("POST", this.server + "/XRMServices/2011/Organization.svc/web", false);
 xmlhttp.setRequestHeader("Accept", "application/xml, text/xml, */*");
 xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
 xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
 if (fUserCallback != null) {
 //asynchronous: register callback function, then send the request.
 var crmServiceObject = this;
 xmlhttp.onreadystatechange = function() {
 fInternalCallback.call(crmServiceObject, xmlhttp, fUserCallback)
 };
 xmlhttp.send(sXml);
 } else {
 //synchronous: send request, then call the callback function directly
 xmlhttp.send(sXml);
 return fInternalCallback.call(this, xmlhttp, null);
 }
 }
 FetchUtil.prototype._HandleErrors = function(xmlhttp) {
 /// <summary>(private) Handles xmlhttp errors</summary>
 if (xmlhttp.status != XMLHTTPSUCCESS) {
 var sError = "Error: " + xmlhttp.responseText + " " + xmlhttp.statusText;
 alert(sError);
 return true;
 } else {
 return false;
 }
 }
 FetchUtil.prototype.Fetch = function(sFetchXml, fCallback) {
 /// <summary>Execute a FetchXml request. (result is the response XML)</summary>
 /// <param name="sFetchXml">fetchxml string</param>
 /// <param name="fCallback" optional="true" type="function">(Optional) Async callback function if specified. If left null, function is synchronous </param>
 var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
 request += "<s:Body>";
 request += "<Execute xmlns='http://schemas.microsoft.com/xrm/2011/Contracts/Services'>" + "<request i:type=\"b:RetrieveMultipleRequest\" " + ' xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" ' + ' xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' + '<b:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">' + '<b:KeyValuePairOfstringanyType>' + '<c:key>Query</c:key>' + '<c:value i:type="b:FetchExpression">' + '<b:Query>';
 request += CrmEncodeDecode.CrmXmlEncode(sFetchXml);
 request += '</b:Query>' + '</c:value>' + '</b:KeyValuePairOfstringanyType>' + '</b:Parameters>' + '<b:RequestId i:nil="true"/>' + '<b:RequestName>RetrieveMultiple</b:RequestName>' + '</request>' + '</Execute>';
 request += "</s:Body></s:Envelope>";
 return this._ExecuteRequest(request, "Fetch", this._FetchCallback, fCallback);
 }

FetchUtil.prototype._FetchCallback = function(xmlhttp, callback) {
 ///<summary>(private) Fetch message callback.</summary>
 //xmlhttp must be completed
 if (xmlhttp.readyState != XMLHTTPREADY) {
 return;
 }
 //check for server errors
 if (this._HandleErrors(xmlhttp)) {
 return;
 }
 var moreRecordsXML = xmlhttp.responseXML.selectSingleNode("//a:MoreRecords").text;
 if (moreRecordsXML == 'true') {
 morePages = 'true';
 pageCookie = xmlhttp.responseXML.selectSingleNode("//a:PagingCookie").text;
 pageCookie = pageCookie.replace( /\"/g , '\'');
 pageCookie = pageCookie.replace( /</g , '&lt;');
 pageCookie = pageCookie.replace( />/g , '&gt;');
 pageCookie = pageCookie.replace( /'/g , '&quot;');
 pageNumber = pageNumber + 1;
 } else {
 morePages = 'false';
 }

// get the value of the morerecords

var sFetchResult = xmlhttp.responseXML.selectSingleNode("//a:Entities").xml;
 var resultDoc = new ActiveXObject("Microsoft.XMLDOM");
 resultDoc.async = false;
 resultDoc.loadXML(sFetchResult);
 //parse result xml into array of jsDynamicEntity objects
 var results = new Array(resultDoc.firstChild.childNodes.length);
 for (var i = 0; i < resultDoc.firstChild.childNodes.length; i++) {
 var oResultNode = resultDoc.firstChild.childNodes[i];
 var jDE = new jsDynamicEntity();
 var obj = new Object();
 for (var j = 0; j < oResultNode.childNodes.length; j++) {
 switch (oResultNode.childNodes[j].baseName) {
 case "Attributes":
 var attr = oResultNode.childNodes[j];
 for (var k = 0; k < attr.childNodes.length; k++) {
 // Establish the Key for the Attribute
 var sKey = attr.childNodes[k].firstChild.text;
 var sType = "";
 // Determine the Type of Attribute value we should expect
 for (var l = 0; l < attr.childNodes[k].childNodes[1].attributes.length; l++) {
 if (attr.childNodes[k].childNodes[1].attributes[l].baseName == 'type') {
 sType = attr.childNodes[k].childNodes[1].attributes[l].text;
 }
 }
 switch (sType) {
 case "a:OptionSetValue":
 var entOSV = new jsOptionSetValue();
 entOSV.type = sType;
 entOSV.value = attr.childNodes[k].childNodes[1].text;
 obj[sKey] = entOSV;
 break;
 case "a:EntityReference":
 var entRef = new jsEntityReference();
 entRef.type = sType;
 entRef.guid = attr.childNodes[k].childNodes[1].childNodes[0].text;
 entRef.logicalName = attr.childNodes[k].childNodes[1].childNodes[1].text;
 entRef.name = attr.childNodes[k].childNodes[1].childNodes[2].text;
 obj[sKey] = entRef;
 break;
 default:
 var entCV = new jsCrmValue();
 entCV.type = sType;
 entCV.value = attr.childNodes[k].childNodes[1].text;
 obj[sKey] = entCV;
 break;
 }
 }
 jDE.attributes = obj;
 break;
 case "Id":
 jDE.guid = oResultNode.childNodes[j].text;
 break;
 case "LogicalName":
 jDE.logicalName = oResultNode.childNodes[j].text;
 break;
 case "FormattedValues":
 var foVal = oResultNode.childNodes[j];
 for (var k = 0; k < foVal.childNodes.length; k++) {
 // Establish the Key, we are going to fill in the formatted value of the already found attribute
 var sKey = foVal.childNodes[k].firstChild.text;
 jDE.attributes[sKey].formattedValue = foVal.childNodes[k].childNodes[1].text;
 }
 break;
 }
 }
 results[i] = jDE;
 }
 //return entities
 if (callback != null) callback(results);
 else return results;
 }

function jsDynamicEntity(gID, sLogicalName) {
 this.guid = gID;
 this.logicalName = sLogicalName;
 this.attributes = new Object();
 }

function jsCrmValue(sType, sValue) {
 this.type = sType;
 this.value = sValue;
 }

function jsEntityReference(gID, sLogicalName, sName) {
 this.guid = gID;
 this.logicalName = sLogicalName;
 this.name = sName;
 this.type = 'EntityReference';
 }

function jsOptionSetValue(iValue, sFormattedValue) {
 this.value = iValue;
 this.formattedValue = sFormattedValue;
 this.type = 'OptionSetValue';
 }







Plugin message for the Marketing list Association to Campaign in MSCRM 2011:


Message : ADDITEM meesage will be fired when Marketing list Association to Campaign but not The Association message

Primary entity is : Campaign

Input parameters received in plugin context is:

1. Entity name: List
2. Campaign id: Campaign Guid
3.  Entity id: Associated marketing List Guid

Sample code:



if (context.InputParameters.Contains("EntityName"))
                        {
                            if (context.InputParameters["EntityName"].ToString() == "list")
                            {
                                if (context.InputParameters.Contains("EntityId"))
                                {
                                    marketingListId = context.InputParameters["EntityId"].ToString();
                                }
                                if (context.InputParameters.Contains("CampaignId"))
                                {
                                    campaignId = context.InputParameters["CampaignId"].ToString();
                                 }
                             }
                         }

Monday 11 March 2013


CRM Diagnostics Page to Capture Network Performance:

Network performance between the client and server will play a key factor in how well CRM performs for the end users. It is very common to have users working from remote locations where the network performance is unknown. There are several methods to test network performance, but since the release of Update Rollup 4 CRM has included its own diagnostics page to show bandwidth, latency and JavaScript Rendering performance



To use the diagnostics page you can simply browse to the page by using the URL http://<YourCRMServerURL>/tools/diagnostics/diag.aspx and click the Run button to start the tests. This page is available for both CRM Online and OnPremise


This CRM Diagnostics page will issue a series of pings from client to server and transfer several blobs of data. Based on this data it will provide the latency in milliseconds and max transfer speeds achieved. This is a quick and easy way to identify the network performance without having to install any tools on the client or server.

In the Optimizing and Maintaining Client Performance for Microsoft Dynamics CRM 2011 and CRM Online document it states that “Microsoft Dynamics CRM is designed to work best over networks with latency under 150 milliseconds”.



How to Debug CRM 2011 online plugin  BY Guru Prasad



 its difficult to debug plugins registered in sandbox on CRM 2011 online version. Follow the Steps to debug plugins registered for online version
  • Install Plugin Pro-filer in the plugin registration Tool.(if you don’t find this option, download latest SDK)
  • Now Register the plug-in and step on the Microsoft Dynamics CRM server. Keep a copy of the debug compiled plug-in assembly on the computer where you are running the tool(@SDK\sdk\tools\pluginregistration\bin\Debug)
  • Select a plug-in step and click Profile to enable profiling.
  •  Perform the operation in Microsoft Dynamics CRM that causes the plug-in to run. Ex: Here updation of Account which trigger the plugin.
  • Now the plug-in throws an exception and the Business Process Error dialog is displayed, click Download Log File and save this file.
  • In the Plug-in Registration tool, click Debug.

  • Debug Dialog will open

            select the Saved Error Log File in the “Profile Location” and then select the Plugin assembly location in the “Assembly Location” where .rdb file available to debug. select the plugin which needs to be debug in the “Plug-in” dropdown list.

    • Now open the plugin solution in Visual Studio and then place the break point to debug, attach the debugger to PluginRegistration.exe process.
    • Click Start Plug-in Execution in the Debug Existing Plug-in dialog box
    • Now the debugger will start debugging from the break point in  the VS. Now you can debug the plugin in the normal way like on-premise.
    Unable to connect to plugin registration toll for online mscrm polaris:

    Try browsing to Settings --> Customizations --> Developer Resources and use the URL under Discovery Service.  It looks like with the change to the new authentication system they changed the default discovery service URL for CRM online to use disco.crm.dynamics.com rather than the old dev.crm.dynamics.com. For the plugin registration tool exclude the /XRMservices/2011/Discovery.svc  part of the url, the tool appends that the URL you enter either way.


    Mscrm 2011 plugin syntax on opportunity lose message:


    public void CloseAssociatedOpportunity(IPluginExecutionContext context, IOrganizationService service)
            {
                if (context.InputParameters.Contains("EntityMoniker") &&
                              context.InputParameters["EntityMoniker"] is EntityReference
                    && context.PostEntityImages.Contains("PostImage") && context.PostEntityImages["PostImage"] is Entity)

                {
                    List<Guid> opportunityIds = new List<Guid>();
                    EntityReference entity = (EntityReference)context.InputParameters["EntityMoniker"];
                    OptionSetValue state = (OptionSetValue)context.InputParameters["State"];
                    OptionSetValue status = (OptionSetValue)context.InputParameters["Status"];

                    //state 1 = Inactivate : state 0 = Activate
                    if (entity.LogicalName == "tls_joborder" && state.Value == 1)
                    {
                        //Fecth the associated Opportunities of the Job Order
                        opportunityIds = GetOpportunitiesIds(service, entity.Id);

                        // Fetching Opportunity selected in the Lookup
                        if(context.PostEntityImages["PostImage"].Contains("tls_opportunity")
                            && !String.IsNullOrEmpty(((EntityReference)context.PostEntityImages["PostImage"].Attributes["tls_opportunity"]).Id.ToString()))
                           opportunityIds.Add(((EntityReference)context.PostEntityImages["PostImage"].Attributes["tls_opportunity"]).Id);

                        if (opportunityIds.Count > 0)
                        {
                            foreach (Guid opprtunityId in opportunityIds)
                            {
                                CloseOpportunitiesAsLost(service, opprtunityId);
                            }
                        }

                    }
                }
            }


    Mscrm 2011 C# code to close the opportunity as Lost :

     public void CloseOpportunitiesAsLost(IOrganizationService service, Guid opportunityId)
            {

                Entity entity = new Entity("opportunityclose");
                entity["opportunityid"] = new EntityReference("opportunity", opportunityId);
                entity["actualend"] = DateTime.Now;
                LoseOpportunityRequest woReq = new LoseOpportunityRequest();            
                woReq.OpportunityClose = entity;
                woReq.Status = new OptionSetValue(-1);
                service.Execute(woReq);

            }

    Mscrm 2011 plugin: direct fetch xml synatx  used for retrieve

     public List<Guid> GetRelatedPracticeGroupIds(IOrganizationService service, Guid accountId)
            {
                List<Guid> PracticeGroupIds = new List<Guid>();
                string fetchXml = @"<fetch version=""1.0"" output-format=""xml-platform"" mapping=""logical"" distinct=""true"">
                          <entity name=""lrl_practicegroup"">
                            <attribute name=""lrl_practicegroupid"" />
                            <order attribute=""lrl_name"" descending=""false"" />
                            <link-entity name=""lrl_lrl_practicegroup_account"" from=""lrl_practicegroupid"" to=""lrl_practicegroupid"" visible=""false"" intersect=""true"">
                              <link-entity name=""account"" from=""accountid"" to=""accountid"" alias=""ac"">
                                <filter type=""and"">
                                  <condition attribute=""accountid"" operator=""eq"" uitype=""account"" value=""" + accountId + @""" />
                                </filter>
                              </link-entity>
                            </link-entity>
                          </entity>
                        </fetch>";

                EntityCollection Result = service.RetrieveMultiple(new FetchExpression(fetchXml));
                if (Result.Entities.Count > 0)
                {

                    foreach (Entity node in Result.Entities)
                    {
                        PracticeGroupIds.Add(node.Id);
                    }
                }
                return PracticeGroupIds;



            }
         
            }



    Update Record In mscrm 2011 form form javascript:


    Soap:



    function updateAccount() {
        var FORM_TYPE_UPDATE = 2;
        var formType = Xrm.Page.ui.getFormType();
        if (formType == FORM_TYPE_UPDATE) {
            // Prepare variables for updating a contact.
            var accountId = Xrm.Page.data.entity.getId();
            var parentAccount = Xrm.Page.getAttribute('parentaccountid');
            var parentAccountId;

            if (parentAccount != null) {

                var lookUpObjectValue = parentAccount.getValue();

                if ((lookUpObjectValue != null)) {

                    parentAccountId = lookUpObjectValue[0].id;

                }
                var authenticationHeader = GenerateAuthenticationHeader();

                // Prepare the SOAP message.
                var xml = "<?xml version='1.0' encoding='utf-8'?>" +
    "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
    " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
    " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
    authenticationHeader +
    "<soap:Body>" +
    "<Update xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
    "<entity xsi:type='account'>" +
    "<parentaccountid>" + parentAccountId + "</parentaccountid>" +
    "<accountid>" + accountId + "</accountid>" +
    "</entity>" +
    "</Update>" +
    "</soap:Body>" +
    "</soap:Envelope>";
                // Prepare the xmlHttpObject and send the request.
                var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
                xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
                xHReq.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Update");
                xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
                xHReq.setRequestHeader("Content-Length", xml.length);
                xHReq.send(xml);
            }
        }
    }




    Rest:

    function updateContactRest() {

        var FORM_TYPE_UPDATE = 2;
        var formType = Xrm.Page.ui.getFormType();
        if (formType == FORM_TYPE_UPDATE) {
            // Prepare variables for updating a contact.
            var accountId = Xrm.Page.data.entity.getId();
            var parentAccount = Xrm.Page.getAttribute('parentaccountid');
            var parentAccountId;

            if (parentAccount != null) {

                var lookUpObjectValue = parentAccount.getValue();

                if ((lookUpObjectValue != null)) {

                    parentAccountId = lookUpObjectValue[0].id;


                }
                // Gets the record Guid
                var id = Xrm.Page.data.entity.getId();
                var changes = {
                    // Text field

                    // Lookup field
                    ParentAccountId: {
                        Id: parentAccountId, // Guid of the parent account
                        LogicalName: "account"
                    }
                };

                //updateRecord exists in JQueryRESTDataOperationFunctions.js
                updateRecord(id, changes, "AccountSet", updateAccountCompleted, null);
            }
        }
    }


    function updateRecord(id, entityObject, odataSetName, successCallback, errorCallback) {
        var context = Xrm.Page.context;
        var serverUrl = context.getServerUrl();

        //The XRM OData end-point
        var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";

        //id is required
        if (!id) {
            alert("record id is required.");
            return;
        }
        //odataSetName is required, i.e. "AccountSet"
        if (!odataSetName) {
            alert("odataSetName is required.");
            return;
        }

        //Parse the entity object into JSON
        var jsonEntity = window.JSON.stringify(entityObject);

        //Asynchronous AJAX function to Update a CRM record using OData
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            data: jsonEntity,
            url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')",
            beforeSend: function (XMLHttpRequest) {
                //Specifying this header ensures that the results will be returned as JSON.          
                XMLHttpRequest.setRequestHeader("Accept", "application/json");

                //Specify the HTTP method MERGE to update just the changes you are submitting.          
                XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
            },
            success: function (data, textStatus, XmlHttpRequest) {
                //The MERGE does not return any data at all, so we'll add the id
                //onto the data object so it can be leveraged in a Callback. When data
                //is used in the callback function, the field will be named generically, "id"
                data = new Object();
                data.id = id;
                if (successCallback) {
                    successCallback(data, textStatus, XmlHttpRequest);
                }
            },
            error: function (XmlHttpRequest, textStatus, errorThrown) {
                if (errorCallback)
                    errorCallback(XmlHttpRequest, textStatus, errorThrown);
                else
                    errorHandler(XmlHttpRequest, textStatus, errorThrown);
            }
        });
    }


    function errorHandler(xmlHttpRequest, textStatus, errorThrow) {
        alert("Error : " + textStatus + ": " + xmlHttpRequest.statusText);
    }

    //Called upon successful Account update.
    function updateAccountCompleted(data, textStatus, XmlHttpRequest) {
        //Get back the Account JSON object
        var account = data;
        // alert("Account updated: id = " + account.id);
    }


















    How to have a custom filtering on lockup using form java script in mscrm 2011: by Srinivas kalwakuntla





    function Accountview() {

        var account = Xrm.Page.getAttribute('tls_parentaccount');
        var accountid;

        if (account != null) {

            var lookUpObjectValue = account.getValue();

            if ((lookUpObjectValue != null)) {

                var lookuptextvalue = lookUpObjectValue[0].name;

                var accountid = lookUpObjectValue[0].id;

            }


            if (!IsNull(accountid)) {
                var viewId = "{1DFB2B35-B07C-44D1-868D-258DEEAB88E2}";
                var entityName = "account";
                var viewDisplayName = "Default View For Account";


                var fetchXml = '<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">' +
                         '<entity name="account">' +
                            '<attribute name="name" />' +
                             '<attribute name="sic" />' +
                            '<attribute name="accountid" />' +
                             '<attribute name="address1_city" />' +
                             '<attribute name="telephone1" />' +
                             '<attribute name="primarycontactid" />' +
                             '<filter type="and">' +
                              '<condition attribute="accountid" operator="ne" value="' + accountid + '"/>' +
                            '</filter>' +
                         '</entity>' +
                      '</fetch>';

                // build Grid Layout
                var layoutXml = "<grid name='resultset' " +
                    "object='1' " +
                    "jump='account' " +
                    "select='0' " +
                    "icon='0' " +
                    "preview='1'>" +
                    "<row name='result' " +
                    "id='accountid'>" +
                    "<cell name='name' " +
                    "width='200' />" +
                    "<cell name='primarycontactid' " +
                    "width='150' />" +
                    "<cell name='sic' " +
                    "width='150' />" +
                    "<cell name='address1_city' " +
                    "width='150' />" +
                    "<cell name='telephone1' " +
                    "width='150' />" +
                    "</row>" +
                    "</grid>";

                Xrm.Page.getControl("new_newemployer").addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, true);
                Xrm.Page.getControl("new_previousemployer").addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, true);

            }

        }
    }





    Javascript code for phone number format in mscrm 2011:by srinivas kalwakuntla


    //Phone Number Format
    function FormatPhoneNumber(context) {
        var oField = context.getEventSource().getValue();
        var sTmp = oField;

        if (typeof (oField) != "undefined" && oField != null) {
            sTmp = oField.replace(/[^0-9]/g, "");
            switch (sTmp.length) {
                case 10:
                    sTmp = sTmp.substr(0, 3) + "-" + sTmp.substr(3, 3) + "-" + sTmp.substr(6, 4);
                    break;


                default:
                    alert("Phone Number must contain 10 numbers.");
                    break;
            }
        }
        context.getEventSource().setValue(sTmp);
    }



    Mscrm 2011 plugin registered on Associate message code:


     //Getting the Relationship Name ,Target(Practice group id) and Relted entity (Account ID)


                        if (!context.InputParameters.Contains("Relationship")) { return; }
                        Relationship relationship = (Relationship)context.InputParameters["Relationship"];
                        if (relationship.SchemaName != "lrl_lrl_practicegroup_account") { return; }
                        if (!context.InputParameters.Contains("Target")) { return; }
                        EntityReference target = (EntityReference)context.InputParameters["Target"];
                        Guid practiceGroupId = target.Id;
                        if (!context.InputParameters.Contains("RelatedEntities")) { return; }
                        EntityReferenceCollection related = (EntityReferenceCollection)context.InputParameters["RelatedEntities"];
                        foreach (EntityReference entityReferenceObj in related)
                        {
                            accountId = entityReferenceObj.Id;
                        }
                         


    Mscrm 2011 plugin: direct fetch XML syntax  used for retrieve:

     public List<Guid> GetRelatedPracticeGroupIds(IOrganizationService service, Guid accountId)
            {
                List<Guid> PracticeGroupIds = new List<Guid>();
                string fetchXml = @"<fetch version=""1.0"" output-format=""xml-platform"" mapping=""logical"" distinct=""true"">
                          <entity name=""lrl_practicegroup"">
                            <attribute name=""lrl_practicegroupid"" />
                            <order attribute=""lrl_name"" descending=""false"" />
                            <link-entity name=""lrl_lrl_practicegroup_account"" from=""lrl_practicegroupid""    to=""lrl_practicegroupid"" visible=""false"" intersect=""true"">
                              <link-entity name=""account"" from=""accountid"" to=""accountid"" alias=""ac"">
                                <filter type=""and"">
                                  <condition attribute=""accountid"" operator=""eq"" uitype=""account"" value=""" +               accountId + @""" />
                                </filter>
                              </link-entity>
                            </link-entity>
                          </entity>
                        </fetch>";

                EntityCollection Result = service.RetrieveMultiple(new FetchExpression(fetchXml));
                if (Result.Entities.Count > 0)
                {

                    foreach (Entity node in Result.Entities)
                    {
                        PracticeGroupIds.Add(node.Id);
                    }
                }
                return PracticeGroupIds;



            }
         
            }