Dynamics CRM Discovery and Web Service URLs

Dynamics CRM Discovery and Web Service URL’s based on the following Dynamics CRM SDK articles.

Discover the URL for your organization with IDiscoveryService web service

Download the endpoints using the Dynamics CRM Developer resources page

Here is the information that you need:

For CRM Online customers:

The following URLs should be used to access the discovery service (use the appropriate URL for your location):

Provider: Microsoft Office 365
https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc (North America)
https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc (EMEA)
https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc (APAC)

Provider: Microsoft Account
https://dev.crm.dynamics.com/XRMServices/2011/Discovery.svc (North America)
https://dev.crm4.dynamics.com/XRMServices/2011/Discovery.svc (EMEA)
https://dev.crm5.dynamics.com/XRMServices/2011/Discovery.svc (APAC)

The following URLs should be used to access the Organization service(SOAP endpoint):

https://{Organization Name}.api.crm.dynamics.com/XrmServices/2011/Organization.svc (North America)
https://{Organization Name}.api.crm4.dynamics.com/XrmServices/2011/Organization.svc (EMEA)
https://{Organization Name}.api.crm5.dynamics.com/XrmServices/2011/Organization.svc (APAC)

Where {Organization Name} refers to the Organization that you specify in the URL when accessing the Web application. For example, for Contoso.crm.dynamics.com, the {Organization Name} is Contoso.

The following URLs should be used to access the Organization Data service(OData REST endpoint)

https://{Organization Name}.api.crm.dynamics.com/XrmServices/2011/OrganizationData.svc (North America)
https://{Organization Name}.api.crm4.dynamics.com/XrmServices/2011/OrganizationData.svc (EMEA)
https://{Organization Name}.api.crm5.dynamics.com/XrmServices/2011/OrganizationData.svc (APAC)

For On-premise
deployments:
http://{server}/XRMServices/2011/Discovery.svc for the Discovery service endpoint
http://{server}/{OrgName}/XRMServices/2011/Organization.svc for the Organization Service endpoint (SOAP)
http://{server}/{OrgName}/XRMServices/2011/OrganizationData.svc for the Organization Data Service endpoint (REST)
http://{server}/XRMDeployment/2011/Deployment.svc for the Deployment Service endpoint

For IFD deployments:

http://dev.{hostname[:port]}/XRMServices/2011/Discovery.svc for the Discovery service endpoint

CRM Online to SharePoint Online Integration using REST and ADFS

Accessing SharePoint Online 2013 REST services with SSO via ADFS (Active Directory Federation Services) from CRM Online provides loads of potential opportunities, especially now that SharePoint offers a huge REST API. You can call REST from a CRM Online Plugin or Custom Workflow activity with no dependencies on SharePoint Client dll’s or Azure getting in the way, It is fairly awesome I must say.

I use the HttpWebRequest class to perform SOAP requests to perform the authentication part of this integration, which is totally supported within Sandboxed Plugins and Custom Workflow Activities. You can read more about the restrictions of the CRM Sandboxed environment here http://msdn.microsoft.com/en-us/library/gg334752.aspx. Once you get authenticated and obtain the cookies you are free to fire REST calls off by simply providing the cookies along with the request.

The best diagram I found to describe the authentication process visually was from Wictor Wilen’s blog http://www.wictorwilen.se/

Auth Process

I wanted to explore the issue of authentication between CRM Online and SharePoint Online from a server to server perspective and as you can imagine authentication is a big hurdle for this direct type of communication as every example I have seen so far includes Azure. Well at least until I started to look at what others were doing with Windows 8 Apps and Active Authentication. Omar Venado http://blogs.msdn.com/b/omarv/ and fellow MVP Wictor Wilen http://www.wictorwilen.se/ had some really great articles to help me build out a solution focused on this scenario. The code attached to this blog is heavily derived from Omar’s Windows 8 App code though now is useable in non Windows 8 App projects such as C# Console, SSIS Packages and of course CRM Plugin/Workflow projects. I have added some background reading at the bottom of this post so you can see the articles I used to get my code to work.

An example of how simple this code is to use

Uri spSite = new Uri(https://myOrg.sharepoint.com/sites/mySite”);

bool success = SpoAuthUtility.Create(spSite, username@domain.com, WebUtility.HtmlEncode(“Pword123″), false);

string odataQuery = “_api/web/lists”;

Uri url = new Uri(String.Format(“{0}/{1}”, SpoAuthUtility.Current.SiteUrl, odataQuery));

// Send a json odata request to SPO rest services to fetch all list items for the list.

byte[] result = HTTPHelper.SendODataJsonRequest(

url,

“GET”, // reading data from SP through the rest api usually uses the GET verb

null,

(HttpWebRequest)HttpWebRequest.Create(url),

SpoAuthUtility.Current // pass in the helper object that allows us to make authenticated calls to SPO rest services

);

string response = Encoding.UTF8.GetString(result, 0, result.Length);

You can authenticate using corporate credentials if inside your network, username/password if outside your network (e.g CRM Online O365) and you can also use your onmicrosoft.com accounts. Remember that my primary focus was on server to server integration possibilities, not user to server contexts such as in the current SharePoint CRM List Component model.

The attached C# Console app contains 3 files to provide you with an example of how to use the 2 cs classes HTTPHelper and SPOAuthUtility. To authenticate and start calling REST from CRM Plugins/Workflows simple include the HTTPHelper and SPOAuthUtility cs files into your Plugin/Workflow project.

Example App is available here https://skydrive.live.com/redir?resid=492A170E77E43399!830

Background reading

http://blogs.msdn.com/b/omarv/archive/2012/10/25/windows-8-store-apps-office-365-enterprise-preview-sharepoint-online.aspx

http://blogs.msdn.com/b/omarv/archive/2012/11/15/developing-windows-store-apps-for-sharepoint-online-with-sso-single-sign-on.aspx

http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx

http://allthatjs.com/2012/03/28/remote-authentication-in-sharepoint-online/

CRM 2011 Validate User Security Roles using JavaScript/REST

This example I’m sharing today is demonstrating a few techniques which promote JavaScript and REST, along with using namespaces and creating a library of functions/properties. This example declares a library Security.UserInRole and defines a number of properties and functions. The general idea is to allow the data access via REST to be asynchronous which then offers a valid and invalid function callback option to be defined to handle the outcome. You can specify an array of security roles to check against the current user and then with the callback functions you can perform the actions that you require.

Ideally I want to call a function that is easy to use and it will look like this.
Security.UserInRole.checkUserInRole(
["System Administrator", "System Customizer", "Custom Role Name"],
function(){alert("valid"); // The user is in one of the specifed roles.
},
function(){alert("invalid"); // The user is not in one of the specifed roles.
}
}

To define the library namespace and object we use
//If the Security namespace object is not defined, create it.
if (typeof (Security) == "undefined")
{ Security = {}; }
// Create Namespace container for functions in this library;
if (typeof (Security.UserInRole) == "undefined") {
Security.UserInRole = {
__namespace: true
};
}

 

The library functions and properties declared include the following
Security.UserInRole = {
isInRole: null,
roleIdValues: [],
validFunction: null,
invalidFunction: null,
checkRoles: [],
checkUserInRole: function (roles, validFunc, invalidFunc) {},
getAllowedSecurityRoleIds: function () {},
validateSecurityRoles: function () {},
querySecurityRoles: function (queryString) {},
__namespace: true
};

 

The entire library is implemented so that you call a function, it performs the processing asynchronously and then gives you the outcome to handle the response. Whether you want to show/hide form elements or disable fields etc, you can handle this in the callback function parameters validFunc and invalidFunc defined in the checkUserInRole function. The entire library content can be placed in a CRM webresource and added to a form. The full library is as shown below.

//If the Security namespace object is not defined, create it.
if (typeof (Security) == "undefined")
{ Security = {}; }
// Create Namespace container for functions in this library;
if (typeof (Security.UserInRole) == "undefined") {
Security.UserInRole = {
isInRole: null,
roleIdValues: [],
validFunction: null,
invalidFunction: null,
checkRoles: [],
checkUserInRole: function (roles, validFunc, invalidFunc) {
validFunction = validFunc;
invalidFunction = invalidFunc;
checkRoles = roles;
Security.UserInRole.getAllowedSecurityRoleIds();
},
getAllowedSecurityRoleIds: function () {
var filter = "";
for (var i = 0; i < checkRoles.length; i++) {
if(filter == "") {
filter = "Name eq '" + checkRoles[i] + "'";
}
else {
filter += " or Name eq '" + checkRoles[i] + "'";
}
}
Security.UserInRole.querySecurityRoles("?$select=RoleId,Name&$filter=" + filter);
},
validateSecurityRoles: function () {
switch (Security.UserInRole.isInRole) {
//If the user has already been discovered in role then call validFunc
case true:
validFunction.apply(this, []);
break;
default:
var userRoles = Xrm.Page.context.getUserRoles();
for (var i = 0; i < userRoles.length; i++) {
var userRole = userRoles[i];
for (var n = 0; n < Security.UserInRole.roleIdValues.length; n++) {
var role = Security.UserInRole.roleIdValues[n];
if (userRole.toLowerCase() == role.toLowerCase()) {
Security.UserInRole.isInRole = true;
// Call function when role match found
validFunction.apply(this, []);
return true;
}
}
}
// Call function when no match found
invalidFunction.apply(this, []);
break;
}
},
querySecurityRoles: function (queryString) {
var req = new XMLHttpRequest();
var url = "";
// Try getClientUrl first (available post Rollup 12)
if (Xrm.Page.context.getClientUrl) {
url = Xrm.Page.context.getClientUrl();
}
else {
url = Xrm.Page.context.getServerUrl();
}
req.open("GET", url + "/XRMServices/2011/OrganizationData.svc/RoleSet" + queryString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null; //Addresses memory leak issue with IE.
if (this.status == 200) {
var returned = window.JSON.parse(this.responseText).d;
for (var i = 0; i < returned.results.length; i++) {
Security.UserInRole.roleIdValues.push(returned.results[i].RoleId);
}
if (returned.__next != null) {
//In case more than 50 results are returned.
// This will occur if an organization has more than 16 business units
var queryOptions = returned.__next.substring((url + "/XRMServices/2011/OrganizationData.svc/RoleSet").length);
Security.UserInRole.querySecurityRoles(queryOptions);
}
else {
//Now that the roles have been retrieved, try again.
Security.UserInRole.validateSecurityRoles();
}
}
else {
var errorText;
if (this.status == 12029)
{ errorText = "The attempt to connect to the server failed."; }
if (this.status == 12007)
{ errorText = "The server name could not be resolved."; }
try {
errorText = window.JSON.parse(this.responseText).error.message.value;
}
catch (e)
{ errorText = this.responseText }
}
}
};
req.send();
},
__namespace: true
};
}

 

To use the library in the onload event of an entity form simply add the Security.UserInRole library webresource to the form and create a another JavaScript web resource to hold the onload function. The onload function may look like this. You define the roles to check as an array and pass this to the checkUserInRole function along with the valid and invalid callback functions. You don’t have to define the functions as anonymous functions like my example below but it can sometimes feel cleaner.

function onload()
{
Security.UserInRole.checkUserInRole(
["System Administrator", "System Customizer", "Custom Role Name"],
function(){alert("valid"); // The user is in one of the specifed roles.
},
function(){alert("invalid"); // The user is not in one of the specifed roles.
}
);
}

 

I would like to mention Jim Daly from the MS CRM Team for his examples of namespace and library structure along with his REST query code as this example I have created is derived from his outstanding work.

Happy Coding..

Silverlight + XRM Book by David Yack MVP

Building the next generation of business applications using Microsoft Silverlight and Dynamics CRM 2011

Fellow MVP David Yack has produced the perfect guide to Silverlight with Dynamics CRM 2011. I highly recommend this book for people new to Silverlight or Dynamics CRM but I also think  those already working with either Silverlight or Dynamics CRM should check it out. I’ve been reading through it this past week and have been learning key things that will help during the design and implementation of my latest projects. I wish I had this book earlier, as my CRM tools on Codeplex could have really benefited from the details in this book too. It shows the knowledge and understanding David has of Microsoft’s latest incarnation of CRM along with Silverlight and how to integrate them.

David Yack MVP is the CTO of Colorado Technology Consultants based in Colorado. He is a Microsoft Regional Director and a Microsoft MVP for Silverlight. This guys knows his stuff…

For an overview of the book’s chapters check it out here, and here is a quick summary of chapter titles.

Chapter 1 – Using Silverlight with CRM 2011 
Chapter 2 – Getting Started
Chapter 3 – XAML 101 and Basic Layout
Chapter 4 – Silverlight Controls
Chapter 5 –Data Binding Basics
Chapter 6 – Application Navigation
Chapter 7 – Out of Browser Support
Chapter 8 – Application Composition with MEF
Chapter 9 – Other Silverlight Business Application Features
Chapter 10 – Enhancing the User Experience
Chapter 11 – Discovering SketchFlow
Chapter 12 –Interacting with CRM Form
Chapter 13 –OData Basics
Chapter 14 –OData Beyond the Basics
Chapter 15 – Using the WCF Service
Chapter 16 – Application Architectures
Chapter 17 –Silverlight Debugging

There is now no excuse for not producing high quality Silverlight apps when developing for Dynamics CRM.

CRM 2011 OData Query Designer

This project is superceded by the new application Dynamics XRM Tools which includes improved features http://dynamicsxrmtools.codeplex.com/

 

I’ve developed the CRM 2011 OData Query Designer as a Silverlight 4 application that is packaged as a Managed CRM 2011 Solution. This tool allows you to build OData queries by selecting filter criteria, select attributes and order by attributes. The tool also allows you to Execute the query and view the ATOM and JSON data returned.  Once the managed solution is imported into CRM 2011 it is accessible from the Settings area under Customizations .

You can download the CRM 2011 OData Query Designer  from codeplex.

[UPDATE]

Latest Update 8th March 2011
1. Added dropdown list of available OptionSet values for a filter when of type OptionSet, Boolean, Status and State.
2. Attribute lists now show the UserLocalizedLabel Display Name instead of Schema Name.
3. Resolved issues with some attribute types not generating correctly when used in a filter.

Has this Tool saved you time…

If you have benefited from downloading and using this tool, please feel free to donate an amount of your choice. Thankyou

GBP – Donate via PayPal - GBP>

USD – Donate via PayPal - USD>

Euro – Donate via PayPal - Euro>