Tuesday, December 27, 2011

Import data now allows you to Create the entities as well

CRM 4.0 made available the feature to import data into CRM using the Import feature. But this was only restricted to importing data in existing entities.


In CRM 2011 this feature has now been extended to go one step further and even create the entity in CRM to hold the data in case an entity for that does not already exist. CRM 2011 also provides us the capability to define the entity attributes as well while importing the data.

Let me explain the step one by one to give the exact understanding of the dynamic concept.

-Click on “Import Data” button


- A dialog to import your CSV data will be displayed as given in the below screen shot.

- After that Dialog to which we want to map the data will be displayed. In that window select the “Create New” as given in the below screen shot. Provide the name for the new entity along with the Primary Field name.
- After that a window to map the attributes to the data will be shown as given below. -For mapping of each column we can create new field as given in the below screen shot. Please make sure to provide mapping for primary field for Ex: in our case “Name”.
- After that a window showing the mapping summary will be displayed as given below.
- After that click on submit button

-After successfully importing the data, you will notice that the custom entity has also been created in CRM. You have to add the fields on the form as it is not implicitly added to the form


Tuesday, December 20, 2011

ODATA Properties and Methods Explored…

Here are some of the ODATA context properties that would help us during debugging and understanding the behavior of the context when performing various operations.
1. DataServiceContext.Entities:
Gets a list of all the records currently being tracked by the DataServiceContext. While using OData service, we frequently get the error that context already tracking the record. With the "Entities" property, we can check total records tracked by context. As well as after adding record to the set, we can check whether context.Entities count increases.

2. DataServiceContext.IgnoreMissingProperties:
Gets or sets whether the properties read from the type must be mapped to properties on the client-side type. Always set this property to true. This helps when say you have downloaded the ODATA reference and developed your application based on that and later there are additional attributes added to the entities. With this property set to True it will ignore the new properties that were added later on and not throw an error regarding missing properties.

3. DataServiceContext.Links:
Gets the collection of all associations or links currently being tracked by the DataServiceContext object which are added using AddRelatedObject, AddLink and SetLink methods.

4. DataServiceContext.AddLink(source, sourceProperty, target):
Adds the specified link to the set of objects the DataServiceContext is tracking. Before adding a link, both source and target must be tracked by context.
Example: context.AddLink(parentRecord, "relationshipName", childRecord);

5. DataServiceContext.SetLink(source, sourceProperty, target):
Notifies the DataServiceContext that a new link exists between the objects specified and that the link is represented by the property specified by the sourceProperty parameter. Before adding a link, both source and target must be tracked by context.
Example: context.AddLink(childRecord, "relationshipName", parentRecord);

6. DataServiceContext.AddRelatedObject(source, sourceProperty, target):
Adds a related object to the context and creates the link that defines the relationship between the two objects in a single request.
Example: context.AddLink(childRecord, "relationshipName", parentRecord);

Note: AddLink and SetLink are very useful methods as using these we can make a compound request (i.e. can add parent and child together). This will only work when your parentLink (a field that is lookup to parent) is not required on child record. When we tried to create an invoice with invoice details, it was giving an error and only invoice header gets created. This is because for Invoice detail, invoiceid is a required field and it cannot be created without and invoice id provided. However this does work in cases, where the child entity can be created independently and the parent entity is not a required attribute in the child entity.


-------------------------------------------------------
Posted by: Inogic
For more information/discussions (documents, sample code snippets, detailed work flow or diagrams),
Please be free to visit the following links or email us:
Web: http://www.inogic.com
Blog: http://inogic.blogspot.com
Email: news@inogic.com
-----------------------------------------------------

Friday, December 16, 2011

Performing CRUD Operations synchronously in CRM 2011 through JSON

Synchronous methods to create, update and delete the records for the Account entity through JSON. These methods works synchronously.

Create Records: To create the record into the CRM, you need to create an object for that record. After that you need to create the object of the XMLHttpRequest and open this request through “POST” method and need to call the send method with this jsonEntity (create from the target record).

function createRecord( ) {
var account = new Object( );
account.Name = "Create Sample";
account.Telephone1 = "555-0123";
account.AccountNumber = "ABCDEFGHIJ";
account.EMailAddress1 = "someone1@example.com";

var jsonEntity = window.JSON.stringify(account);
var createRecordReq = new XMLHttpRequest( );
var ODataPath = Xrm.Page.context.getServerUrl( ) + "/XRMServices/2011/OrganizationData.svc";
createRecordReq.open('POST', ODataPath + "/" + "AccountSet", false);
createRecordReq.setRequestHeader("Accept", "application/json");
createRecordReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
createRecordReq.send(jsonEntity);

var newRecord = JSON.parse(createRecordReq.responseText).d;
//Alert the Id of the created record
alert("Id is: " + newRecord.AccountId);
}

Update Record: Update record request is same as the create but for the Update we need to set the Additional request header for the Method in the XMLHttpRequest. Here we have added the “MERGE” method. As shown below.
updateRecordReq.setRequestHeader("X-HTTP-Method", "MERGE");

And when we open the request, we need to pass the guid of the record. As given in the below script.

function updateRecord( ) {
var account = Object( );
account.Name = "Update Name of this Account";
var jsonEntity = window.JSON.stringify(account);
var updateRecordReq = new XMLHttpRequest( );
var ODataPath = Xrm.Page.context.getServerUrl( ) + "/XRMServices/2011/OrganizationData.svc";
updateRecordReq.open('POST', ODataPath + "/" + "AccountSet" + "(guid'" + "E72B45B9-58E0-E011-B700-00155D005515" + "')", false);
updateRecordReq.setRequestHeader("Accept", "application/json");
updateRecordReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
updateRecordReq.setRequestHeader("X-HTTP-Method", "MERGE");
updateRecordReq.send(jsonEntity);

}

Delete Record: This is same as update request but here we need to call the Method delete and call send method with the null parameter.

function deleteRecord( ) {
var deleteRecordReq = new XMLHttpRequest( );
var ODataPath = Xrm.Page.context.getServerUrl( ) + "/XRMServices/2011/OrganizationData.svc";
deleteRecordReq.open('POST', ODataPath + "/" + "AccountSet" + "(guid'" + "E72B45B9-58E0-E011-B700-00155D005515" + "')", false);

deleteRecordReq.setRequestHeader("Accept", "application/json");
deleteRecordReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
deleteRecordReq.setRequestHeader("X-HTTP-Method", "DELETE");
deleteRecordReq.send(null);

}


-------------------------------------------------------
Posted by: Inogic
For more information/discussions (documents, sample code snippets, detailed work flow or diagrams),
Please be free to visit the following links or email us:
Web: http://www.inogic.com
Blog: http://inogic.blogspot.com
Email: news@inogic.com
-----------------------------------------------------

Tuesday, December 13, 2011

Read records synchronously using JSON in CRM 2011

Common knowledge is that we can make JSON requests through scripts in CRM 2011 to retrieve data from CRM entities. However, the JSON request works asynchronously i.e it does not return the results immediately and the control moves to the next line of code to be executed.

It so happened during one of our development sessions is that we had to write a script to populate the values of some attributes on a form based on the value entered in another form, similar to the usual copy the phone and email once the contact is selected. We had written the JSON code for this but because it executed asynchronously the control would return to the user even before the code execution completed and the phone and email was populated on the form. The user would click on Save and Close and reported an issue that it did not bring over the phone and email…

We can replace JSON with SOAP and get this done. But we thought of getting this done by executing JSON request synchronously now that we already has the code in there to execute the call through JSON.
function retrieveRecordsSynchronously() {

var retrieveRecordsReq = new XMLHttpRequest();
var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/AccountSet";
retrieveRecordsReq.open('GET', ODataPath, false);
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.send(null);
var records = JSON.parse(retrieveRecordsReq.responseText).d;
//Read the first account name
alert('First Account Name is: ' + records.results[0].Name);
}
As given in the above code we need to create the object of the XMLHttpRequest and need to open this request through ‘GET’ method. And after setting the header of this request we need to just call the send Method to send the request, after that we need to parse the response text of the request and from that we can read the results.

We are reading from AccountSet and it returns an array of accounts. Note it would only return 50 results at a time.