Monthly Archives: September 2012

CRM2011 training . SDK, Office 365 login and CRM Online.

To train some developers at our office we used the SDK 5.0.12 with CRM2011 Online and Office 365 login approach.

When we downloaded the SDK we found several problems while using the SDK tools mainly with the ExportRibbon utility and the Plugin Registration tool.

All the problems were related to connexion and once we found a way to connect those tools to the CRM everything worked smooth.

I will describe the solutions we found to fix those problems.

Problem 1: Plugin Registration Tool –> The service is unavailable.

We found 3 problems with the PluginRT ,

First of all we hadn´t installed the Windows Identity Foundation tools and we couldn´t build the C# project due to IDentityModel issues.
If you have the same problem please download the right version of Windows Identity Foundation for your system from here .

Second, we had connection problems with the message “service unavailable” or “proxy requires auth”. To fix this issue we just added an app.config file to the Plugin RT with the following code were we specify our proxy settings.


<configuration>
  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true">
      <proxy bypassonlocal="True" proxyaddress="http://100.100.300.200:8080" />
    </defaultProxy>
  </system.net>
</configuration>

Finally we had some problems at one of the machines due to time mismatch between CRM2011 server and the developer machine.
You can change the server time zone in the File/Options menu of CRM and make sure is the same that your clock time zone.
After that using the prompt command “w32tm /resync” you will have your computer synchronized with the internet global time zone setting.

Problem 2: Exported Ribbon XML –> Username and Password must be provided.

When executing the exportRibbonXML project we had some connexion problems with the following message: “username and password must be provided.”.

These message was shown before the tool asked for a username or password. Debugging the tool we manage to jump the step where the connexion was made and
pass to the step where the name and password where input. After that, the connexion was made and the tool created a XML file with the credentials.

If you try to connect again , the tool will check for this file and follow to correct sequence to connect without problems.

If you are experiencing the same problems I suggest you copy this XML, write your organization and username values and save it as Credentials.xml in the

C:\Users\<yourLoginUser>\AppData\Roaming\CrmServer folder.

<?xml version="1.0" encoding="utf-8"?>
<Configurations>
  <Configuration>
    <ServerAddress>crm4.dynamics.com</ServerAddress>
    <OrganizationName>futbol</OrganizationName>
    <DiscoveryUri>https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc</DiscoveryUri>
    <OrganizationUri>https://realmadrid.api.crm4.dynamics.com/XRMServices/2011/Organization.svc</OrganizationUri>
    <HomeRealmUri>
    </HomeRealmUri>
    <Credentials>
      <UserName>realmadrid@realmadrid.onmicrosoft.com</UserName>
    </Credentials>
    <EndpointType>OnlineFederation</EndpointType>
    <UserPrincipalName>
    </UserPrincipalName>
  </Configuration>
</Configurations>

CRM2011 – C# Datatypes

These are the common datatypes relations between CRM2011 and C# types.

 

CRM2011  Visual Studio 2010 Asign Command SQL Server
EntityReference Entity[“Field”] = new EntityReference(“Entity Related”, Data Type Guid(“Related Entity ID”)) uniqueidentifier
Client Entity[“Field”] = new EntityReference(“Entity Related(account/contact)”, Data Type Guid(“Related Entity ID”)) uniqueidentifier
OptionSet Entity[“Field”] = new OptionSetValue(Data Type Int) int
Currency Entity[“Field”] = new Money(Data Type Decimal) money
2 options Entity[“Field”] = Data Type Bool bit
DateTime Entity[“Field”] = Data Type Datetime o Datetime.ToString(“format”) datetime
Line of text Entity[“Field”] = Data Type String nvarchar
Decimal Number Entity[“Field”] = Data Type Decimal decimal
Integer Number Entity[“Field”] = Data Type Int int
Double Entity[“Field”] = Data Type Double float
Owner Entity[“Field”] = new EntityReference(“Related Entity(systemuser)”, Data Type Guid(“Related Entity ID”)) uniqueidentifier
Long Text Entity[“Field”] = Data Type String (long text) nvarchar(-1)

CRM2011 Creating Many to Many relationshios via C#

Creating Many to Many relationshios via C#

  
EntityCollection eBarrera;
eBarreraC = getCond(barrera);

GestionGUID.GuidCondicionantes = new Guid(eBarreraC.Entities[0].Id.ToString());

string strManyToManyRelationshipName = "chm_chm_cond_contact";

AssociateEntitiesRequest request = new AssociateEntitiesRequest();
request.Moniker1 = new EntityReference { Id = idAseg, LogicalName = "contact" };
request.Moniker2 = new EntityReference { Id = GestionGUID.GuidCon, LogicalName = "chm_con" };
request.RelationshipName = strManyToManyRelationshipName;
servicio.Execute(request);

JavaScript Querying the CRM2011 Web services

As we all know JavaScript is a Script language that executes on the client machine-browser. Based on the information loaded in the current opened page-form we can do many actions all of them executed on the client machine without needing the network connection (hide/show fields, modify attribute values, check the current user role… and more ). These JavaScript features make faster the system response to the user actions.

But sometimes we need information about CRM entities not included in the current page-form so we need to query the CRM2011 web services to get more data,create, update or delete records or make other service calls.

To archive this goal with JavaScript we can use 2 methods:

Both ways are fully documented in the SDK but if you don’t feel like reading it all i will explain here the easiest way to use both of them and the libraries needed.

The main different for me is that I used Asynchronous calls with ODATA(although u could change the Ajax query type to make them synchronous) and Synchronous calls with Fetch.

By Asynchronous I mean that the JavaScript execution will continue after making the QueryCall without waiting for the response indicating in the query to which function will have to call the server after executing the QueryCall.

When the query has been executed it will call this “return” JavaScript function where we will be able to process the result data.

A synchronous call will wait until the execution has finished to continue with the next instruction.

Reading some posts about these two ways of querying CRM2011 people comment that the Rest End Point is more efficient but you can only use simple commands (Retrieve,Create,Update or Delete records) while the SOAP end point is a bit slower but lets you make more complex actions(like making service requests).

Both ways of interacting with the CRM2011 Web Services are useful and fully working so i suggest you read both posts and decide which one fits you better.

Have a nice day,

Hache

CRM2011 JavaScript calls using CrmServiceToolkit SOAP Endpoint.

To be able to query the CRM2011 Web Services using de SOAP END POINT we need a SDK library called CrmServiceToolkit.js embebed in the page-form from where we want to make JavaScript queries.
I have attached the library as a .doc document (cause WordPress don’t allow to upload .js files). Please download it here and change the file extension to .js to be able to add it to you CRM2011 as a web resource. You will need as well the opensource jquery and json libraries.

As I explained before, the main different between this type of call and the ODATA rest endpoint calls is that they work as synchronous calls which means that after the query has been made, the JavaScript execution will stop running until the response has arrived.

Once you have the library in your form, we can make SOAP queries using this simple commands.

Retrieve Record

var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C';
var cols = ["firstname", "lastname", "birthdate", "email"];
var retrievedContact = CrmServiceToolkit.Retrieve("contact", contactId, cols);

alert(retrievedContact.getValue('lastname'));
alert(retrievedContact.getValue('firstname'));

Fetch Queries

var fetchXml = [   
"<fetch mapping='logical'>",   
   "<entity name='contact'>",   
	  "<attribute name='createdby' />",   
	   "<filter type='and'>",   
		 "<condition attribute='createdby' operator='eq-userid'/>",   
		 "<condition attribute='contactid' operator='eq' value='",crmForm.ObjectId, "' />",   
		"<condition attribute='createdon' operator='last-x-hours' value='1' />",   	
	  "</filter>",   
   "</entity>",   
"</fetch>"  
].join(""); 

 var fetcheUsuario = CrmServiceToolkit.Fetch(fetchXml);

The only difficult thing here is creating the fetch command. But as you will probably know, using the CRM2011 Advance Find tools we can create queries as complex as we need an convert them to fetch XML with just one click.

Get fetch from Advance Find Tools

Get fetch from Advance Find Tools

Querying by Attributes

var queryOptions = {
   entityName : "contact",
   attributes : ["name", "contactid","surname","mainphone"],
   values : ["peter", "680","griffin","919191919"],
   columnSet : ["chm_idproducto_1"],
   orderby : ["surname"]
		};

var fetchedContacts = CrmServiceToolkit.queryByAttribute(queryOptions);

Retrieve Multiple

var firstname = 'Hache';
var query = [].join("");

var retrievedContacts = CrmServiceToolkit.RetrieveMultiple(query);

Creating Records

var contactrecord = new CrmServiceToolkit.BusinessEntity("contact");
contactrecord.attributes["Name"] = "Peter";
contactrecord.attributes["SurName"] = "Griffing";
var createResponse = CrmServiceToolkit.Create(contactrecord);

Updating Records

ar contactId = '4D507FFE-ED25-447B-80DE-00AE3EB18B84';
var contact = new CrmServiceToolkit.BusinessEntity("contact");
contact.attributes["contactid"] = contactId;
contact.attributes["address1_line1"] = "45 green St.";

CrmServiceToolkit.Update(contact);

Deleting Records

var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C';
var deleteResponse = CrmServiceToolkit.Delete("contact", contactId);
alert(deleteResponse);

And these are the most common functions that we can use using the CRMService SOAP EndPoint. Some of this info was found here.

If you want to get information about the CRM211 Odata queries REST END POINT just read my post about it.

As i explained in previos posts, SOAP Point querys are less efficient than Rest Point queries but more powerfull. With Rest we can not make service calls while with SOAP we can do it this way.

Service calls

var whoAmI = CrmServiceToolkit.Execute("");
currentUserId = whoAmI.getElementsByTagName("UserId")[0].childNodes[0].nodeValue;
alert("Current user's ID is " + currentUserId);

CRM2011 JavaScript Querying using ODATA Rest EndPoint

To use the CRM2011 ODATA Rest EndPoint querying functions you need a Jquery Library, a JSon library and a SDK library embebed in the page-form from where you want to make JavaScript queries.

I have joined these three libraries in a single one called ODATA Libraries.js. Here i attach the file ODATALibraries.doc (cause wordpress dont let me upload .js files). Download it and change the file extension to .js to be able to use it in your CRM2011. ODATALibraries Javascript file

We have to understand that ODATA querying is ASYNCHCHRONOUS which means that our Javascript will make a call and continue running without waiting for a response. Thats why when we make the call we will have to tell the system which function the system will have to call when finishing the execution of our call. We can aswell expecify a function that the system will call in case it has some problem or error during the Query execution.

With this knowledge and the file included in our form as a JavaScript web resource, you will be able to make calls to the CRM2011 webservices this easy way.

Retrieve Single Record

retrieveRecord(id,"AccountSet", retrieveAccountCompleted, function4Errors);

Retrieve Multiple Records

To retrive multiple we need to provide a ODATA qyery where we can specify the fields we want to retrieve, the condition they must complete and the order in which we want the results.

To create this Odata querys i recomend this tool (Odata Query designer) that will generate the queries for you in less than 1 second.

 retrieveMultiple("EntitySet", "?$filter=contactid/Id eq guid'{FFFFFFFFF}'", GetContactsCompleted, function4Errors);

The 4 parameters of this query are:

  1. EntitySet : Entity you want to query.
  2. OData Query: Fields we want to retrieve, condition and order.
  3. Success Callback Function: The control will be returned to this function after the asynchronous call finish execution.
  4. Error Callback Function: In case of error during the query execution the control will be returned to this function.

To process the result data you should do something like this:

function GetContactsCompleted(data, textStatus, XmlHttpRequest)
{
	var accounts = data;
	if (accounts.length > 0)
	{
		for (var i = 0; i < accounts.length; i++)
		{
			var ac = accounts[i];
			if(ac != null && ac.Name != 'myname')
			{
				var name = ac.Name;
				var surname = ac.Surname;
				//......
			}
		};
	}
}

Creating , Updating and Deleting Records.


//Creates an Account record
function createAccount() {

 //Create an object to represent an Account record and supply a single field "Name"
 var account = new Object();
 account.Name = "Sample Account created via OData jQuery library.";
 account.Surname = "Whatever.....";

  //createRecord exists in odatalibreries.js
 createRecord(account, "AccountSet", createAccountCompleted, function4Errors);
}

//Updates an Account record
function updateAccount(id) {

  //Instantiate an Account object and modify some fields. You'll only need to
 //provide the fields you want changed because updateRecord() uses an HTTP MERGE
 var changes = new Object();
 changes.Name = "Updated Sample";
 changes.Telephone1 = "555-0123";
 changes.AccountNumber = "ABCDEFGHIJ";
 changes.EMailAddress1 = "someone1@example.com";

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

//Prompts user if he/she wants to delete the Account record. Deletes record is yes.

function deleteAccount(id) {
 if (confirm("Do you want to delete this account record?"))
 {
 //deleteRecord exists in odatalibreries.js
  deleteRecord(id, "AccountSet", deleteAccountCompleted, function4Errors);
 }
 }
}

//------------------------------------------------------------
//Callback functions
function function4Errors(XmlHttpRequest, textStatus, errorThrown)
{
    alert('There was an error executing your command.');
}

//Called upon successful Account creation.
function createAccountCompleted(data, textStatus, XmlHttpRequest) {
 //Get back the Account JSON object
 var account = data;
 showMessage("Account created with id: " + account.AccountId.toString());
}

//Called upon successful Account retrieval.
function retrieveAccountCompleted(data, textStatus, XmlHttpRequest) {
 //Get back the Account JSON object
 var account = data;
 showMessage("Account retrieved: account name = \"" + account.Name +
        "\", id = {" + account.AccountId + "}");
}

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

//Called upon successful Account deletion.
function deleteAccountCompleted(data, textStatus, XmlHttpRequest) {
 showMessage("Account deleted.");
}

//Function to display information on the host HTML page.
function showMessage(message) {
var div = $("</pre>
<div>").html(message);
 $("#status").append(div);
}

I hope this helps.If you want to get information about Querying CRM2011 using the CrmServiceToolkit SOAP Endpoint read my post here.

Have a nice day.

Hache

Great post about how to use Fetch with JavaScript

Hosk's Dynamic CRM Blog

[tweetmeme source=”BenHosk” only_single=false]

The chaps over at Customer Effective blog have written a really interesting blog post this week.  It’s called

Execute Fetch from Javascript in CRM 2011

They actually also wrote an interesting article about why Microsoft buying skype made sense, which you can read here, I found this interesting because I was thinking Microsoft had completely overpaid but then the article  mentions skype have 636 million users, Microsoft paid $8.6 billion and that works out at $14.70 per/user price.  Now that’s not much for each users and you would probably think that skype is going to grow the number of users it has.  You can see Microsoft bundling skype in with Xbox, CRM and office etc.  The last thought I had was Microsoft has money burning a hole in it’s pocket.  The only danger is that someone else/Google could create a skype competitor but then I thought the same…

View original post 762 more words