Reputation:
I'm connecting successfully to on-premise server using the organization service by this code.
using (OrganizationServiceProxy proxy = new OrganizationServiceProxy(
Organization,
HomeRealm,
CredentialsForClient,
CredentialsForDevice)) { ... }
Organization
is our server plus the suffix OrgName/XRMServices/2011/Organization.svc
. CredentialsForClient
is my log-in (or my live ID when going for on-line). HomeRealm
and CredentialsForDevice
are set to null
.
This appears to work perfectly for on-premise version but when I go on-line, I get an error. I can create the proxy
variable but when I attempt to execute the code below, the exception tells me that I can't have a null
value as an end point. This is hardly telling me anything, due to my ignorance.
EntityCollection entityCollection = proxy.RetrieveMultiple(fetchExpression);
Of course I'm using a different Organization
when going on-line. I copied the string from the settings of our on-line version of CRM Dynamics (just as I did for the on-premise version). How can I tackle this problem?
Upvotes: 3
Views: 8452
Reputation: 1129
When connecting to an online version, you have to give device credentials as well as user credentials. Just the way it is (Windows live authentication scheme and all.)
Edit
After some bit of research, I still have not found official documentation as to why this is. Generally, on the MSDN forums it is accepted that this is to associate give a device identity to windows live. Maybe this is so Microsoft can track what workstations are using CRM? Maybe it enables them to enhance security at some point by restricting which machine identities may connect to CRM using certain accounts. Maybe all/none of the above.
Speculation aside, in my experience, I have not been able to execute a successful query without device credentials authenticated against the CRM (i.e. through the OrganizationServiceProxy
constructor or the Authentication process used by the IServiceManagment implementations.)
Below, you will find some older code that I was using to do this. I now recommend using the connection string as mentioned by @Jason Lattimer. If you need to handle more parallelism, look into using IServiceManagement<IOrganizationService>
.
var reader = new AppSettingsReader();
//instatantiate credential class and populate values
var cc = new ClientCredentials();
cc.UserName.UserName = reader.GetValue("WLID", typeof(string)).ToString();
cc.UserName.Password = reader.GetValue("WLPS", typeof(string)).ToString();
//repeat for device credentials
var deviceCredentials = new ClientCredentials();
deviceCredentials.UserName.UserName = reader.GetValue("deviceWLID", typeof(string)).ToString();
deviceCredentials.UserName.Password = reader.GetValue("deviceWLPS", typeof(string)).ToString();
//create a uri for the organization service location
#if DEBUG
var orgServiceUri = new Uri(reader.GetValue("CrmNonProductionUri", typeof(string)).ToString());
#else
Uri orgServiceUri = new Uri(reader.GetValue("CrmProductionUri", typeof(string)).ToString());
#endif
OrganizationServiceProxy retval = new OrganizationServiceProxy(orgServiceUri, null, cc, deviceCredentials);
retval.EnableProxyTypes();
So, in the end, I just use a config file to store the various values needed to construct my credentials and uri (for both environments.)
Upvotes: 1
Reputation: 17562
Have you seen this sample, it shows how to Authenticate Users with Microsoft Dynamics CRM Web Services without any helper code for all types of connection, on-premise, on-line.
Upvotes: 3
Reputation: 2848
You might want to download the latest version of the SDK and look at the example: Simplified Connection to Microsoft Dynamics CRM. Connection strings differ between on premise and online.
[<add name="Server=CRM Online, organization=YourOrg, user=YourUserName"
connectionString="Url=https://YourOrg.crm.dynamics.com; [email protected]; Password=YourPassword"/>][2]
Upvotes: 3