Early binding tips and tricks for Dynamics CRM 2011
When you’re working with Dynamics CRM 2011 and you need to write plugins or other kinds of integration with .NET code you should make use of early binding. This gives you a context that contains a typed .NET representation of all your entities, relations, …
var contacts = from c in context.ContactSet
where c.FirstName == "Sandrino"
select c;
foreach (var contact in contacts)
{
Console.WriteLine(contact.FullName);
}
The fact that you have a 1 on 1 representation of all your entities and relations has a lot of advantages:
- You no longer have to work with magic strings when accessing attributes
- Every property is typed the correct way. No need to cast attribute values anymore.
- When entities or attributesare removed, renamed, … and you update your context your code won’t build and you can fix each problem immediately. No more runtime errors.
- Less bugs
- Less manual work
- …
This context is created based on the metadata of your organization. To view the metadata of your organization you just need to navigate to the following URL: http://server/organization/XRMServices/2011/OrganizationData.svc/$metadata
In Visual Studio you can use this URL to add a Service Reference and have some code generated but I wouldn’t advise this. Instead you should use a tool that comes with the CRM SDK named CrmSvcUtil.exe When you start using this tool you’ll quickly bump into the same error over and over again:
Exiting program with exception: The caller was not authenticated by the service. Enable tracing and view the trace files for more information.
Let’s run over a few tips on how you could solve this issue:
Proxy Settings
When you’re working inside a corporate network that only allows network access via a proxy server you’ll need to create a new file in the same directory as CrmSvcUtil.exe and name it crmsvcutil.exe.config Now this file should contain the proxy settings for the application, and it most cases it should look like this:
<?xml version="1.0"?>
<configuration>
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true"/>
</system.net>
</configuration>
This forces the application to use the proxy and to use the default credentials. If you are still having problems and you’re working behind an ISA Proxy you might want to install the Microsoft Firewall Client Management tool from Microsoft. This will help you with most other authentication problems.
Finding the actual error
The error message specifies that you should take a look at the trace files to find the actual error. This trace file is located in the C:\Program Files\Microsoft Dynamics CRM\Trace directory.
Look for the file with the most recent date modified that looks like the file on the screenshot. This will contain the trace message with a detailed exception:
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/nl-BE/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>/LM/W3SVC/2/ROOT-1-129423140458251760</AppDomain>
<Exception>
<ExceptionType>System.ComponentModel.Win32Exception, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The Security Support Provider Interface (SSPI) negotiation failed.</Message>
<StackTrace>
at System.ServiceModel.Security.WindowsSspiNegotiation.GetOutgoingBlob(Byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
> at System.ServiceModel.Security.SspiNegotiationTokenAuthenticator.ProcessNegotiation(SspiNegotiationTokenAuthenticatorState negotiationState, Message incomingMessage, BinaryNegotiation incomingNego)>
</StackTrace>
<ExceptionString>System.ComponentModel.Win32Exception (0x80004005): The Security Support Provider Interface (SSPI) negotiation failed.</ExceptionString>
<NativeErrorCode>8009030C</NativeErrorCode>
</Exception>
</TraceRecord>
In this case the exception string will help me to find the solution.
The Security Support Provider Interface (SSPI) negotiation failed.
If you’re working with a virtual machine that is part of an other domain you might get this error (cross domain call). To solve this you’ll need to change the way you pass the authentication arguments to CrmSvcUtil.exe Instead of calling CrmSvcUtil.exe using the following line:
CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:Context.cs
/username:"sandrino" /password:"pass" /domain:"somedomain" /serviceContextName:Context
Change it to the following:
CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:Context.cs
/username:"sandrino@somedomain" /password:"pass" /serviceContextName:Context
By removing the domain argument and appending the domain to the username (separated with the @ sign) you’ll solve the cross domain problem.
Other authentication problems
This might be a no-brainer but it will help. If for some reason you find yourself with authentication problems it might have to do with one of the arguments you are passing to CrmSvcUtil.exe That’s why it’s best to wrap all argument values with double quotes.
CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:"Context.cs"
/username:"sandrino@somedomain" /password:"pass" /serviceContextName:"Context"
Creating a useful batch file
To make sure you can easily updateyour context class you should automate this process. In my case I created a batch file with only 1 command:
CrmSvcUtil\CrmSvcUtil.exe /url:http://server/Contoso/XRMServices/2011/Organization.svc
/out:"..\Sandrino.CRM.Contoso.Common\ContosoContext.cs" /username:sandrino@CONTOSO
/password:"mypwd" /serviceContextName:ContosoContext
Now each time I execute the batch file it will call CrmSvcUtil with the correct arguments and overwrite the existing ContosoContext.cs file in my Sandrino.CRM.Contoso.Common project. I don’t need to memorize the arguments and I don’t need to copy paste the file around. Remember if you are working with TFS you need to check out the file first!
This is how my solution looks like:
Download the sample project: Sandrino.CRM.Contoso.zip (423.70 kb)