Dynamics CRM with a side of URL builder logic 

Since the release Microsoft CRM 4.0, the logic of how the system configures internal URLs has been cloudy at best and limited at worse.  Fortunately based on customer feedback and a very responsive Sustained Engineering Team at Microsoft, the capabilities of this logic have been expanded.  The importance of this is to enable CRM to work in more and more environments.  Have a web server that doesn’t respond to “localhost”?  No problem use a new registry key.  Have web servers that HTTP but a load balancer that offloads and processes HTTPS?  No problem, use a new registry key.  With this flexibility has come complexity and in today’s post, our “guest blogger” Nathan Bell provides some insight:

Overview

The URLs used by various components of Microsoft Dynamics CRM are constructed dynamically using a combination of database entries, registry entries, and hard-coded string literals. The implementation for the dynamic URL building is not encapsulated within a single method or class. The manner in which these URLs are constructed (algorithm used) is not consistent across all areas of CRM. To further complicate matters the settings that drive the construction, and the associated algorithms are not documented. This article is an attempt to document these dynamic URL constructions.

Each section in this article will attempt to define the construction method used by a particular CRM component. Within each section the description will be done in two ways. The first way is in pseudo code shorthand that developers familiar with CRM will probably find to be the most useful, because of its brevity. The second way will be with prose that describes the same information in more detail.

In all sections the construction of a URL is broken down into three parts: protocol, domain, port. Using an example URL of https://crm.microsoft.com:5555/ the parts are: protocol (https), domain (crm.microsoft.com), port (5555).

Note: The logic defined in this post is only effective as of rollup update #5. See the following KB article for more details: http://support.microsoft.com/kb/959758/


Common Definitions

The following shorthand is used by all the pseudo code in this document.

  • “Reg” refers to the registry key: HKLM/software/Microsoft/MSCRM
  • “Dmreg” refers to the registry key: HKLM/software/Microsoft/Data Migration Wizard
  • “Db” refers to the CRM configuration database: MSCRM_CONFIG. Specifically it refers to key/value pairs found in the table “DeploymentProperties”. The key column is “ColumnName” and the value column is “NVarCharColumn”.

In the details sections when a value from the configuration database is reference it will be assumed that the value retrieved from the database was in the MSCRM_CONFIG database, in the table “DeploymentProperties”. Further it is assumed that the value was retrieved from the column “NVarCharColumn” and that the column “ColumnName” was used to match the key.


Asynchronous Service

Pseudo code

Protocol = Reg.ADRootDomainScheme?? Db.ADRootDomainScheme
DomainAndPort= db.AsyncSdkRootDomain?? ("localhost" + reg.LocalSdkPort)
Url = Protocol + "://" + DomainAndPort

Details

The “ADRootDomainScheme” value from the registry will be used for the protocol unless it does not exist, in which case the value from the configuration database will be used instead. The value “AsyncSdkRootDomain” from the configuration database will be used for both domain and port unless it does not exist in which case the domain will be set to the hard-coded string literal “localhost” and the port will be the value found in the registry value “LocalSdkPort”.

NOTE: For the database value “AsyncSdkRootDomain” the port will be encoded into the field along with the domain. For example, “crm.microsoft.com:5555”. If a port is not encoded in the domain value then the port will be assumed to be 80 if the protocol is HTTP and 443 if the protocol is HTTPS.


Plug-in:

Pseudo code

Protocol = reg.ADRootDomainScheme?? Db.ADRootDomainScheme
Domain = reg.LocalSdkHost ?? "localhost"
Port = reg.LocalSdkPort ?? String.Empty
URL = Protocol + "://" + Domain + Port

Details

The “ADRootDomainScheme” value from the registry will be used for the protocol unless it does not exist, in which case the value from the configuration database will be used instead. The value “LocalSdkHost” from the registry will be used for domain unless it does not exist in which case the domain will be set to the hard-coded string literal “localhost”. The value “LocalSdkPort” from the registry will be used for port unless it does not exist in which case it will be empty. An empty port will be assumed to be port 80 if the protocol is HTTP and 443 if the protocol is HTTPS


Discovery Service:

Pseudo code

If(!IsNullOrEmpty(reg.ADRootDomainScheme) && !IsNullOrEmpty(reg.ADSdkRootDomain)
&& !IsNullOrEmpty(reg.ADWebApplicationRootDomain))
{
       SDKURL = reg.ADRootDomainScheme + "://" + reg.ADSdkRootDomain
       WEBURL = reg.ADRootDomainScheme + ://" + reg.ADWebApplicationRootDomain + "/" + CRMORGNAME
}
Else
{
       SDKURL = db.ADRootDomainScheme + "://" + db.ADSdkRootDomain
       WEBURL = db.ADRootDomainScheme + ://" + db.ADWebApplicationRootDomain + "/" + CRMORGNAME
}

Details

In this component either all three values are read from the registry, or they are all read from the configuration database. To say it another way, if any of the registry keys do not exist or are empty then the values from the configuration database will be used. In this component the names of the keys are the same in both the registry and the configuration database.

NOTE: For the database values “AsyncSdkRootDomain” and “ADWebApplicationRootDomain” the port will be encoded into the field along with the domain. For example, “crm.microsoft.com:5555”. If a port is not encoded in the domain value then the port will be assumed to be 80.

 

Data Migration Manager Client:

Pseudo code

URL = Dmreg.ServerUrl + "/2007/crmservice.assmx"

Details

Unlike other components the data migration client does not attempt to read from the configuration database. It will only use the “ServerUrl” value from the registry which will contain all three components (protocol, domain, port).

 

 

Cheers,

 

This posting is provided "AS IS" with no warranties, and confers no rights.
Comments
Hi Aaron ,
If I am not wrong , Same problem , different time :)

I wrote a function for request from CRM via query by ascentium js library.I think it's additional improvement for me :)

Thanks.

function GetServerUrl(slash,portAdd,portNo)
{
var getUrlX = document.location.href.toString();
var xTempUrl = '';
var fTemp = 0;
for(var f=0;f<getUrlX.length;f++)
{
if (getUrlX.charAt(f)=='/'){
fTemp++;
}
if (slash) {
xTempUrl = xTempUrl+getUrlX.charAt(f);
if (fTemp==3){
if (portAdd){
xTempUrl = xTempUrl.substring(0, xTempUrl.length-1);
xTempUrl = xTempUrl+":"+portNo+"/";
}
break;
}
} else {
if (fTemp==3) {
if (portAdd){
xTempUrl = xTempUrl+":"+portNo;
}
break;
} else {
xTempUrl = xTempUrl+getUrlX.charAt(f);
}
}
}
return xTempUrl;
}

usage :

var xLink1 = GetServerUrl(true,true,"66");
xmlHttpObjForThird.open('GET', xLink1+'CRMGenericResults.aspx?xProcType=user&userid='+getpIdX3+'&orgid=conta&teamid=B909FF69-12B7-DE11-A7D6-002264FC96B8', true);
xmlHttpObjForThird.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttpObjForThird.onreadystatechange = function()
{
.....
Add a New Comment
Name

Email Address

Url

Comment