Wednesday, October 17, 2012

MS CRM Online Video Library

Good one, have a look at the CRM online Video library.

Demo CRM Online

  
Hth,
Chaitanya...

Wednesday, June 27, 2012

Dealing with Dates in ODATA Endpoints.

I quote from MSDN:

When you retrieve records using the REST endpoint date values are returned as strings that use the format “\/Date()\/” where is the number of milliseconds since midnight January 1, 1970. For example: "\/Date(1311170400000)\/". All values returned from Microsoft Dynamics CRM represent the Universal Coordinated time (UTC) values.

Sample Code:

Note: In the below code sample "result" is the response from the ODATA querry.

//Retrieving the Date object as string
var stringDateValue = eval(result.CreatedOn).toString();               

Once the string date values are converted to Date objects you can use a variety of JScript methods to display the date as a string that can be displayed in a user interface .

var createdOn  = new Date(parseInt(stringDateValue.replace("/Date(", "").replace(")/", ""), 10)); 
createdOn = getODataLocalDateFilter(createdOn);

function getODataLocalDateFilter(date) {
//-- Description: For converting the date object to local time format
//-- You can also convert this to UTC Date format
//-- UTC Usage: getUTCMonth(), getUTCFullYear(), getUTCHours() ...
 var monthString;
 var rawMonth = (date.getMonth()+1).toString();
 if (rawMonth.length == 1) {
  monthString = "0" + rawMonth;
 }
 else
 { monthString = rawMonth; }
 var dateString;
 var rawDate = date.getUTCDate().toString();
 if (rawDate.length == 1) {
  dateString = "0" + rawDate;
 }
 else
 { dateString = rawDate; }

 var DateFilter = "";
 DateFilter += date.getFullYear() + "-";
 DateFilter += monthString + "-";
 DateFilter += dateString;
 DateFilter += " T" + date.getHours() + ":";
 DateFilter += date.getMinutes() + ":";
 DateFilter += date.getSeconds() + ":";
 DateFilter += date.getMilliseconds();

 return DateFilter;
}

Have fun working with ODATA!!

Tuesday, June 26, 2012

Updating the Owner in CRM.


For updating the Owner field programatically, we need to make use of the Assignrequest message. I have captured the sample code to update the Owner Id in CRM 4.0 and CRM 2011.

Updating the Owner Id in CRM 4.0:

Note: Plase, make sure to update the "ownerUpdatingEntity" with one you are trying to update. Also, Replace the "Entity_Name" with the name of the entity you are updating.

private static void AssignUser(CrmService service, Guid ownerId, Guid recordId)
{
 SecurityPrincipal assignee = new SecurityPrincipal();
 assignee.PrincipalId = ownerId;
 TargetOwnedDynamic ownerUpdatingEntity = new TargetOwnedDynamic();

 ownerUpdatingEntity.EntityId = recordId;
 ownerUpdatingEntity.EntityName = "Entity_Name";

 AssignRequest assign = new AssignRequest();

 assign.Assignee = assignee;
 assign.Target = ownerUpdatingEntity;

 AssignResponse assignResponse = (AssignResponse)service.Execute(assign);
}


Updating the Owner Id in CRM 2011:

Note: Please, make sure to replace the "Account.EntityLogicalName" with the right Entity in the below code.
 

private static void AssignUser(IOrganizationService service, Guid ownerId, Guid recordId)
{
 // Create the Request Object and Set the Request Object's Properties
 AssignRequest assign = new AssignRequest
 {
   Assignee = new EntityReference(SystemUser.EntityLogicalName, ownerId),
   Target = new EntityReference(Account.EntityLogicalName,recordId)
 };
 // Execute the Request
 service.Execute(assign);
}

Hope this helps!

 

Tuesday, June 5, 2012

Retrieve Plugin: MS CRM 2011

I was curious in retrieving the information from the context in Retrieve Plugin message. I realized that the context.InputParameters[“Target”], would return null/ throw exception in the retrieve plugin message.
  1.  To overcome that and to access the attribute collection through the context, here are the steps.
Plugin Configuration


2. The changes that needs to go in to the Plugin Retrieve message code. We need to make use of the OutputParameters collection.

            var orderRetrieve = (Entity) context.OutputParameters["BusinessEntity"];
            DateTime? date = null;
            if (orderRetrieve.Attributes.Contains("modifiedon"))
                date = (DateTime)orderRetrieve.Attributes["modifiedon"];



Also, couple of constraints, that I noticed in the Retrieve message plugin,
·         We cannot debug the Retrieve plugin by throwing an exception, in turn, we will not be able to see the tracing messages.
·         We cannot run plugin profiler to debug.

There is a way to handle the above constarints. will be blogging it on those topic soon...

Monday, January 30, 2012

Dealing with N:N Relationship in MS CRM - 2011

In the latest version of MS CRM 2011, the AssociateEntitiesRequest class has been deprecated. Now, we need to make use of AssociateRequest Class.

Here is an example to associate an entity record.

// Create the request object and set the monikers with the
// orderproduct_association relationship.
AssociateRequest productOrder = new AssociateRequest
{
    Target = new EntityReference(order.EntityLogicalName, orderId),
    RelatedEntities = new EntityReferenceCollection
    {
        new EntityReference(product.EntityLogicalName, productId)
    },
    Relationship = new Relationship("orderproduct_association")
};

// Execute the request.
_serviceProxy.Execute(productOrder);

Thursday, November 10, 2011

context.Depth in Plugin

All,

I was facing a weird issue, when updating an entity from another entity. Let me be more clear in what I mean with an example as explained below.

Example:

  • I had registered a Plugin on Entity A


  • I had another plugin registered on Entity B


  • To meet one of the Business scenario, I was doing an Update from the Entity B on Entity A


  • There was also a workflow which was running on Entity B


  • The Issue was when updating Entity B, the execution context in Entity A was getting in to an infilite loop and was throwing up an exception.

    Inorder to overcome the above scenario, we need to make use of the context.Depth property.

    Here is how it works:
    1) The value of context.Depth property == 1 (when the plugin was initiated from an Entity A [where the plugin was registered])
    2) The value of context.Depth property == 2 (when the plugin was initiated from an Entity B and the value of Depth is 2 in the execution context of Entity A, when the update happening from an Entity B.
    3) The value of context.Depth property == 3 when the Plugin context enters Entity A from a workflow.

    To overcome the above scenario's, fallowing is the code that you need to add it in your Plugin execute method.
    if (context.Depth > 1)
     {
        return; 
     }
    

    Hope this helps,
    Chaitanya...

    Tuesday, November 8, 2011

    Retrieving all the record from an entity

    By default, the RetrieveMultiple method retrieves only 5000 records, this is a limit from the standpoint of performance. In order to retrieve more than 5000 records, please fallow the pattern explained in the below code.

    I have written a console application to retrieve all the Account records. The below code is a method to achieve that. The main logic in retrieving all the records is by passing the PageInfo object to a QueryExpression.
    private static void GetAllActiveAccounts(OrganizationServiceProxy service)
    {
    EntityCollection retrieved;
    const int servicePageSize = 5000;
    int pageNumber = 1;
    string pagingCookie = string.Empty;
    const int pageSize = servicePageSize;
    int totalRecordsCount = 0;
    
    do
    {
    var cols = new ColumnSet();
    cols.AddColumns(new string[] { ACCOUNT_ID, ACCOUNT_NAME });
    var filter = new FilterExpression { FilterOperator = LogicalOperator.And };
    filter.AddCondition(new ConditionExpression(STATE_CODE, ConditionOperator.Equal, new object[] { 0 }));
    
    
    var query = new QueryExpression
    {
    ColumnSet = cols,
    Criteria = filter,
    EntityName = ENTITY_ACCOUNT,
    PageInfo = new PagingInfo()
    {
    PageNumber = 1,
    Count = pageSize
    }
    };
    
    if (pageNumber != 1)
    {
    query.PageInfo.PageNumber = pageNumber;
    query.PageInfo.PagingCookie = pagingCookie;
    }
    
    retrieved = service.RetrieveMultiple(query);
    if (retrieved.MoreRecords)
    {
    pageNumber++;
    pagingCookie = retrieved.PagingCookie;
    }
    
    try
    {
    if (retrieved.Entities.Count > 0)
    {
    totalRecordsCount += retrieved.Entities.Count;
    
    foreach (var accountEntity in retrieved.Entities)
    {
    if (accountEntity.Attributes.Contains(ACCOUNT_ID))
    {
    var accountId = (Guid)accountEntity.Attributes[ACCOUNT_ID];
    var accountName = (string)accountEntity.Attributes[ACCOUNT_NAME];
    Console.WriteLine("Account Name: " + accountName);
    }
    }
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    Console.ReadLine();
    }
    
    } while (retrieved.MoreRecords);
    
    Console.WriteLine("Total records: " + totalRecordsCount);
    }