Posted on 12. January 2013

getServerUrl is Deprecated. Use getClientUrl instead.

Although at the time of writing UR12 is not yet released - I was checking though the changes in the latest SDK documentation.

In addition to the Ribbon Workbench being listed (yay!) I noticed the following statement about the getServerUrl function

"Deprecated. Use getClientUrl instead. This method is deprecated as of Microsoft Dynamics CRM 2011 Update Rollup 12 and the Microsoft Dynamics CRM December 2012 Service Update."

 

Out with the old

 

Using getServerUrl on it's own always had the potential to cause 'Access Denied' messages if the browser domain Url was different to the server Url stored in the CRM database. This was to do with cross domain access restrictions in IE. A work around was to use a method similar to Daniel Cai gives in his post on the subject - http://danielcai.blogspot.co.uk/2012/02/get-right-server-url-in-your-crm-client.html

In with the new

The SDK described the new getClientUrl as:

"Returns the base URL that was used to access the application."

The function nolonger blindly return the server Url in the database - but looks at the url that was used to access CRM so that cross domain access issues will be a thing of the past!

Read more in the SDK:
http://msdn.microsoft.com/en-us/library/d7d0b052-abca-4f81-9b86-0b9dc5e62a66#BKMK_getClientUrl

@ScottDurow

 

Posted on 15. December 2010

Things Dynamics CRM 4.0 Developers must know about CRM 2011 #1:

Nulls are handled differently by the SDK Web services:

Using the CRM 4.0 SDK webservice and pipeline context, you could always exclude an attribute from an update by setting it to null. This has now changed:

CRM 4.0:

entity.attributename = null;

CRM 2011:

entity.Remove("attributename");

 

Data loss when using the RESTfull endpoint

When using the CRM 4.0 SDK  Webservices, you could choose to only return certain attribute values and then when updating only update those values provided whilst leaving the rest the same as they were on the server. This is very desirable to facilitate concurrency (we don't want to send any update to an attribute if we are not actually updating it) and to minimise the traffic between the client and server (don't send/return every attribute with each call).

In CRM2011 however using the OData endpoint this is no longer possible. All values must be retrieved and re-set when updating.

For example, we can use projection onto an Entity to manipulate the $select on the OrganisationData.svc:

 var queryVar = from c in _context.ContactSet
                  where c.FullName.Contains(criteria)
                  select new Contact {
                    FullName = c.FullName,
                    Telephone1 = c.Telephone1,
                    EMailAddress1 = c.EMailAddress1,
                    FirstName = c.FirstName,
                    LastName = c.LastName,
                    Address1_Line1 = c.Address1_Line1,
                    Address1_City = c.Address1_City,
                    Address1_StateOrProvince = c.Address1_StateOrProvince,
                    Address1_PostalCode = c.Address1_PostalCode
                };

This code uses the following GET:

http://{server}:5555/{orgname}/xrmservices/2011/organizationdata.svc/ContactSet()?$filter=FullName%20eq%20'{crtieria}'&$select=FullName,Telephone1,EMailAddress1,etc...

This will only pull down the attributes we need to display.

All good so far.

However, when using the DataContext to update the record on the server using:

_context.BeginSaveChanges(OnSaveContactsComplete, TheMainViewModel.Contacts);
...

We find that all the data that we didn't include in the $select is now nulled out.

This is a common problem with ADO.Net data services and is indeed detailed as "Data loss might occur in the data service when you save updates that were made to projected types." in http://msdn.microsoft.com/en-us/library/ee473425.aspx

This seems like a big flaw to the OData endpoint - in that it forces us to retrieve all values if we want to make any updates at all via the Client OData API. This might be a good reason to avoid the RESTful endpoint unless you know up front that you will never be updating data. The overhead having to retrieving *all* values before performing an update is not something that you want.

 

There is always an exception...

Since JScript RESTful operations use the JSON notation to send data to the server rather than the OData framework, we can perform partial updates as shown by this JScript in the SDK example 'JScriptRestDataOperations:

function updateAccountRecord(Id) {

 var updateAccountReq = new XMLHttpRequest();
 var changes = new Object();
 changes.Name = "Updated Sample";
 changes.Telephone1 = "555-0123";
 changes.AccountNumber = "ABCDEFGHIJ";
 changes.EMailAddress1 = "someone1@example.com";

 updateAccountReq.open("POST", ODataPath + "/AccountSet(guid'" + Id + "')", true);
 updateAccountReq.setRequestHeader("Accept", "application/json");
 updateAccountReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
 updateAccountReq.setRequestHeader("X-HTTP-Method", "MERGE");
 updateAccountReq.onreadystatechange = function () {
  updateAccountReqCallBack(this, Id);
 };
 updateAccountReq.send(JSON.stringify(changes));
}

This code will only update the Name, Telephone1, AccountNumber and EmailAddress1 attributes, and leave the rest unchanged. Note that the attribute names are Case Sensitive.