Friday 30 March 2012

Limitations of OData EndPoint in CRM 2011

1) The $format and $inlinecount operators are not supported. $filter, $select, $top, $skip, $orderby are supported.

2) Maximum 6 expansions are allowed using $expand operator. Querying a multi-level relationship property is not supported i.e. One level of navigation property selection is allowed.

3) Page size is fixed to max 50 records however it can be changed by doing changes in advanced configuration settings but it is not recommended.

4) When using with distinct queries, we are limited to the total (skip + top) record size = 5000. In CRM the distinct queries does not use paging cookie and so we are limited by the CRM platform limitation to the 5000 record.

5) Conditions on only one group of attributes are allowed. A group of attribute refers to a set of conditions joined by And/Or clause.

6) Arithmetic, datetime and math operators are not supported.

7) Order by clause is only allowed on the root entity.

8) Only Create, Retrieve, Update and Delete actions can be performed on entity records.

Messages that require the Execute method cannot be performed.

Associate and Disassociate actions are performed as updates.

9) Authentication is only possible within the application; Use of the REST endpoint is effectively limited to JScript libraries or Silverlight Web Resources.

10) The OData protocol is not fully implemented in CRM 2011. Some system query options are not available.

Friday 23 March 2012

oData and Jscript in CRM 2011

oData is also referred as Open Data Protocol. CRM 2011 mainly uses Windows Communication Foundation (WCF) data services framework to provide oData Endpoint which is nothing but a REST based data service. The address for the endpoint is:

http://{OrganizationRootUrl} /XRMServices/2011/OrganizationData.svc

oData uses some data  format for sending and receiving the data. Basically it uses the following two formats.
  1. ATOM: It is an Xml based format mainly used for the RSS feeds.
  2. JSON: JavaScript Object Notation is a text formats which makes very easy for the developers to understand the response what we get.
We would be using the JSON format in our example.

The main OData service:

http://{OrganizationRootUrl} /XRMServices/2011/OrganizationData.svc

Examples:
1) For retrieving any EntitySet(here GoalSet )
http://{OrganizationRootUrl} /XRMServices/2011/OrganizationData.svc/GoalSet

2) For retrieving limited attributes use $select query option
http://{OrganizationRootUrl}/XRMServices/2011/OrganizationData.svc/GoalSet ?$select=IsAmount,MetricId
This will retrieve collection of IsAmount and MetricId for all Goals.

3) For retrieving data filtered on some criteria use $filter query option
http://{OrganizationRootUrl}/XRMServices/2011/OrganizationData.svc/GoalSet ?$select=IsAmount,MetricId &$filter=GoalId eq guid'" + goalid + "'";
This will retrieve IsAmount and MetricId for the Goal whose GoalId matches with the value of given goalid.

4) For retrieving data from related entity use $expand query option
http://{OrganizationRootUrl}/XRMServices/2011/OrganizationData.svc/GoalSet ?$select=IsAmount,metric_goal/Name,metric_goal/OrganizationId&$expand=metric_goal&$filter=GoalId eq guid'" + goalid + "'";

Here ‘metric_goal’ is the relationship property which defines realtionship between Goal and GoalMetric.

This retrieves IsAmount from GoalSet .Name and Organizationid are fetched from the related GoalMetricSet.

Microsoft Dynamics CRM 2011 does not support querying a multi-level relationship property.Maximum 6 expansion are allowed .

Following is an example for implementing oData using javascript in CRM 2011 to retrieve the required fields from Goal and Goal Metric entities.

clip_image002

As viewed in the snapshot above, three libraries have been included . It is compulsory to include jquery1.4.1.min.js and json2.js for implementing JSON format with oData.Both the files are available in SDK\ samplecode\ js\ restendpoint\restjquerycontacteditor\restjquerycontacteditor \scripts.The third file Goal.js contains two functions as given below i.e. ‘GetIsAmount’ and ‘RetrieveReqCallBack’ which are used to retrieve values for different fields like IsAmount(from Goal entity), Name and OrganisationId(from GoalMetric entity).
function GetIsAmount() {
var goalid = Xrm.Page.data.entity.getId();
var oDataPath = Xrm.Page.context.getServerUrl() + "/xrmservices/2011/organizationdata.svc";
var retrieveReq = new XMLHttpRequest();
var Odata = oDataPath + "/GoalSet?$select=IsAmount,metric_goal/Name,metric_goal/OrganizationId&$expand=metric_goal&$filter=GoalId eq guid'" + goalid + "'";
retrieveReq.open("GET", Odata, false);
retrieveReq.setRequestHeader("Accept", "application/json");
retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveReq.onreadystatechange = function() { RetrieveReqCallBack(this); };
retrieveReq.send();
}
function RetrieveReqCallBack(retrieveReq) {
var metricId = null;
if (retrieveReq.readyState == 4 /* complete */) {
var retrieved = JSON.parse(retrieveReq.responseText).d;
var isAmount = retrieved.results[0].IsAmount;
var Name = retrieved.results[0].metric_goal.Name;
var OrganizationId = retrieved.results[0].metric_goal.OrganizationId;        
}
}

Monday 12 March 2012

Read Configuration file (Web resource - Data (Xml)) in CRM-Plugin

Sometimes, we would like to read data of configuration file which has been added as web resource of type Data (Xml) in Dynamic CRM.

In this example I’ve used a web resource named as “TestData.xml” which contains Data in xml format as shown below (Organization name and Entity name). I would like to explain how to read Organization name from this web resource, a Data (Xml) file.

clip_image002

Add the following class files in your class library project from this location “..\sdk\samplecode\cs\helpercode” once you have successfully downloaded Dynamics CRM SDK 5.0.9 (http://www.microsoft.com/download/en/details.aspx?id=24004).

· crmservicehelpers.cs
· myorganizationcrmsdktypes.cs
· optionsets.cs

Below is the code to retrieve a web resource record.
using System.Xml.Linq;
using Microsoft.Xrm.Sdk.Query;
 
//create request to retrieve Webresource 
QueryByAttribute requestWebResource = new QueryByAttribute
{
EntityName = WebResource.EntityLogicalName,
ColumnSet = new ColumnSet(true),
};
requestWebResource.Attributes.AddRange(“name”);
requestWebResource.Values.AddRange(“acm_/XML/TestData.xml”); 
 
WebResource webResource = null;
EntityCollection webResourceCollection = organizationService.RetrieveMultiple(requestWebResource);
if (webResourceCollection.Entities.Count == 0)
throw new InvalidPluginExecutionException("Specified Webresource does not exist");
 
webResource = (WebResource)webResourceCollection.Entities[0];
 
byte[] binary = Convert.FromBase64String(webResource.Attributes[“content”].ToString());
string resourceContent = UnicodeEncoding.UTF8.GetString(binary);

Once you retrieve a data xml record in above “webResource” variable then convert the content attribute in byte array. By using “UnicodeEncoding” class we will get an encoded string which can be further used with XDocument class.

//Load xml document
XDocument xDoc = XDocument.Parse(resourceContent);
string orgName= string.Empty;
XElement orgNameElement = xDoc.XPathSelectElement("//OrgName");
if (orgNameElement != null)
orgName = orgNameElement.Value;
I hope this will be helpful.

Monday 5 March 2012

Pass Data from an Entity form to an embedded Silverlight Web Resource

While developing a Silverlight Web Resource (XAP) to be viewed on an entity form in Dynamics CRM 2011, sometimes we require to access contextual information of the form. In this post I’ve explained the same with source code.
Below screen shot helps you in inserting a Silverlight web resource on your custom entity via entity customization. Go to default solution/your custom solution, open an entity form and click on Insert tab to insert a Web Resource.

image

To retrieve Object type code and the other contextual data you have to check the Pass record object-type code and unique identifier as parameters option.
Use custom parameter (data) to pass any data which you would like to use in your Silverlight user control highlighted in below screen shot.

image

These values can be accessible in Silverlight control via InitParams, a dictionary of key/value pairs. Below table will help you to use an appropriate parameter in accessing the form values.

Parameter Name Description
typename Entity Name The name of the entity.
type Entity Type Code An integer that uniquely identifies the entity in a specific organization.
id Object GUID The GUID that represents a record.
orgname Organization Name The unique name of the organization.
userlcid User Language Code The language code identifier being used by the current user.
orglcid Organization Language Code The language code identifier that represents the base language for the organization.
data Optional Data Parameter An optional value that may be passed.

Use below source code to retrieve required values in your Silverlight user control.
xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
 
if (xrm == null)
{throw new Exception("Failure: Xrm retrieving..."); }
 
//Set values for ObjectTypeCode, Attribute Name and Entity Name
if (App.Current.Host.InitParams.ContainsKey("type"))
string entityTypeCode = App.Current.Host.InitParams["type"];
 
if (App.Current.Host.InitParams.ContainsKey("typename"))
string entityTypeName = App.Current.Host.InitParams["typename"];
 
//returns value of custom parameter “acm_accname”.
if (App.Current.Host.InitParams.ContainsKey("data"))
string attributeName = App.Current.Host.InitParams["data"];

I hope this will be helpful.