MS Visual C# 2008 Express Edition CRM Discovery Service Walkthrough 18may09 johnpfeiffer
- In Microsoft Visual Studio 2005, on the File menu, point to New, and then click Project to open the New Project dialog box.
- In the Project types pane, select Visual C#.
- In the Templates pane, click Console Application.
- Type a name for your project and then click OK.
To add the CrmDiscoveryService Web service reference :
In the Solution Explorer window, right-click your project name and choose Add Web Reference.
In the Add Web Reference wizard, type the URL for the CrmDiscoveryService Web service in the URL box, using the name and port number for your Microsoft Dynamics CRM server, and then click Go. For example:
http://<servername:port>/mscrmservices/2007/AD/CrmDiscoveryService.asmx
e.g. http://crm/mscrmservices/2007/AD/CrmDiscoveryService.asmx
When the CrmDiscoveryService Web service is found, change the text in the Web reference name box to CrmSdk.Discovery and then click Add Reference. - NOTE old instructions list Web Reference
CLICK ON ADVANCED! Add Web Reference is a wrapper over wsdl.exe and can be used to create proxies for .NET 1.1 or 2.0 clients.
Of course this means when you are pointing to a WCF service you have to be pointing to an endpoint that uses basicHttpBinding (as I was).
Repeat the same process for the CrmService Web service reference (CrmSdk)
http://<servername:port>/mscrmservices/2007/CrmServiceWsdl.aspx
NOW that the services are available, write the code that "instantiates" them to use them...
Add the following lines of code above the namespace statement in your project: [C#] using System.Web.Services.Protocols; using System.Xml;
To include the required Microsoft Dynamics CRM Web service namespaces Add the following lines of code after the namespace statement and before the class statement:
// Import the Microsoft Dynamics CRM namespaces - MS are f*k sh*t, you need to have the app name in the using...
using ConsoleApplication1.CrmSdk;
using ConsoleApplication1.CrmSdk.Discovery;
This code also adds an AuthenticationType class that is used later in the sample code.
// This class is found in Microsoft.Crm.Sdk.dll. You can add a reference
// to the DLL and remove this class definition if you like.
public sealed class AuthenticationType
{
public const int AD = 0;
public const int Passport = 1;
public const int Spla = 2;
}
To add configuration information to your solution Add the following code after the class statement and before the Main method. This code sets up the necessary variables such as organization name.
Be sure to fill in the correct values for the server name, TCP port, and organization of your Microsoft Dynamics CRM installation.
[C#]
#region Configuration data
// The following configuration data is site specific.
// TODO: Set the name and TCP port of the server hosting Microsoft Dynamics CRM.
static private string _hostname = "localhost";
static private string _port = "80";
// TODO: Set the target organization.
static private string _organization = "AdventureWorksCycle";
#endregion Configuration data
// Expired authentication ticket error code. The error codes can be found in the
// SDK documentation at Server Programming Guide\Programming Reference\Error Codes.
// USELESS IN NEW SDK DEMO static private string ExpiredAuthTicket = "8004A101";
To add error handling to your solution
Add the following code within the Main method. This code will provide some console output you can use to verify that your program is working.
[C#]
try
{
Run();
Console.WriteLine("Authentication was successfull.");
}
catch (System.Exception ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine(ex.Message);
// Display the details of the inner exception.
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
SoapException se = ex.InnerException as SoapException;
if (se != null)
Console.WriteLine(se.Detail.InnerText);
}
}
finally
{
Console.WriteLine("Press <Enter> to exit.");
Console.ReadLine();
}
To add the Run method
This method contains all the code needed to use the Discovery service to obtain the correct URL of the CrmService Web service for your organization.
Add the following code after the Main method.
[C#]
/// Authenticates an Active Directory user with Microsoft Dynamics CRM. Afterwards,
/// a call to a CrmService Web method is attempted to verify that the
/// authentication was valid.
///
///
CrmDiscoveryService discoveryService = new CrmDiscoveryService();
discoveryService.UseDefaultCredentials = true;
discoveryService.Url = String.Format(
"http://{0}:{1}/MSCRMServices/2007/{2}/CrmDiscoveryService.asmx",
_hostname, _port, "AD");
// STEP 2: Retrieve the organization name and endpoint Url from the
// CrmDiscoveryService Web service.
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgResponse =
(RetrieveOrganizationsResponse)discoveryService.Execute(orgRequest);
OrganizationDetail orgInfo = null;
foreach (OrganizationDetail orgDetail in orgResponse.OrganizationDetails)
{
if (orgDetail.OrganizationName.Equals(_organization))
{
orgInfo = orgDetail;
break;
}
}
if (orgInfo == null)
throw new Exception("The organization name is invalid.");
// STEP 3: Create and configure an instance of the CrmService Web service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD;
token.OrganizationName = orgInfo.OrganizationName;
CrmService crmService = new CrmService();
crmService.Url = orgInfo.CrmServiceUrl;
crmService.CrmAuthenticationTokenValue = token;
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
// STEP 4: Invoke CrmService Web service methods.
WhoAmIRequest whoRequest = new WhoAmIRequest();
WhoAmIResponse whoResponse = (WhoAmIResponse)crmService.Execute(whoRequest);
return true;
}
// Handle any Web service exceptions that might be thrown.
catch (SoapException ex)
{
throw new Exception("An error occurred while attempting to authenticate.", ex);
}
}
To add the GetErrorCode method Add the following code, after the Run method, for the GetErrorCode method that extracts a numeric error code from a SoapException stored in an XmlNode or returns an empty string if no error exists. [C#] private static string GetErrorCode(XmlNode errorInfo) { XmlNode code = errorInfo.SelectSingleNode("//code");
if (code != null)
return code.InnerText;
else
return "";
}
Typical MS bs... you have to be careful and basically rework all of the instructions, so include references... (all of the things in "using" need to be connected through the project menus...
IN SUMMARY: Compiled and Run! =) THE WORKING VARIABLES AND CODE...
- New Project, Type = C# Console
- Add Reference to .NET -> System.Web.Services
- Add WebReference Microsoft CrmSdk.Discovery http://crm/mscrmservices/2007/AD/CrmDiscoveryService.asmx
- Add WebReference CrmSdk http://crm/mscrmservices/2007/CrmServiceWsdl.aspx
Note In the C# version of the code, if you get a build error of "The type or namespace name 'CrmSdk' could not be found," You must rename the line to using applicationname.CrmSdk
using System; using System.Web.Services.Protocols; using System.Text; using System.Net; using System.Xml;
namespace program { using ConsoleApplication1.CrmSdk; using ConsoleApplication1.CrmSdk.Discovery;
// This class is found in Microsoft.Crm.Sdk.dll. You can add a reference
// to the DLL and remove this class definition if you like.
public sealed class AuthenticationType
{
// Fields
public const int AD = 0;
public const int Passport = 1;
public const int Spla = 2;
}
public class ADAuthentication
{
#region Configuration data
// The following configuration data is site specific. You will need to
// change these data values to those that are appropriate for your
// Microsoft Dynamics CRM installation.
// TODO: Set the name and TCP port of the server hosting Microsoft Dynamics CRM.
static private string _hostname = "crm";
static private string _port = "80";
// TODO: Set the target organization.
static private string _organization = "Anders";
#endregion Configuration data
[STAThread]
public static void Main(string[] args)
{
try
{
ADAuthentication.Run();
Console.WriteLine("Authentication was successfull.");
}
catch (System.Exception ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine(ex.Message);
// Display the details of the inner exception.
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
SoapException se = ex.InnerException as SoapException;
if (se != null)
Console.WriteLine(se.Detail.InnerText);
}
}
finally
{
Console.WriteLine("Press <Enter> to exit.");
Console.ReadLine();
}
}
/// <summary>
/// Authenticates an Active Directory user with Microsoft Dynamics CRM. Afterwards,
/// a call to a CrmService Web method is attempted to verify that the
/// authentication was valid.
/// </summary>
/// <returns>True if successfull, otherwise false.</returns>
public static bool Run()
{
try
{
// STEP 1: Instantiate and configure the CrmDiscoveryService Web service.
CrmDiscoveryService discoveryService = new CrmDiscoveryService();
discoveryService.UseDefaultCredentials = true;
discoveryService.Url = String.Format(
"http://{0}:{1}/MSCRMServices/2007/{2}/CrmDiscoveryService.asmx",
_hostname, _port, "AD");
// STEP 2: Retrieve the organization name and endpoint Url from the
// CrmDiscoveryService Web service.
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgResponse =
(RetrieveOrganizationsResponse)discoveryService.Execute(orgRequest);
OrganizationDetail orgInfo = null;
foreach (OrganizationDetail orgDetail in orgResponse.OrganizationDetails)
{
if (orgDetail.OrganizationName.Equals(_organization))
{
orgInfo = orgDetail;
break;
}
}
if (orgInfo == null)
throw new Exception("The organization name is invalid.");
// STEP 3: Create and configure an instance of the CrmService Web service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD;
token.OrganizationName = orgInfo.OrganizationName;
CrmService crmService = new CrmService();
crmService.Url = orgInfo.CrmServiceUrl;
crmService.CrmAuthenticationTokenValue = token;
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
// STEP 4: Invoke CrmService Web service methods.
WhoAmIRequest whoRequest = new WhoAmIRequest();
WhoAmIResponse whoResponse = (WhoAmIResponse)crmService.Execute(whoRequest);
return true;
}
// Handle any Web service exceptions that might be thrown.
catch (SoapException ex)
{
throw new Exception("An error occurred while attempting to authenticate.", ex);
}
}
/// <summary>
/// Returns the error code that is contained in SoapException.Detail.
/// </summary>
/// <param name="errorInfo">An XmlNode that contains application specific error information.</param>
/// <returns>Error code or zero.</returns>
private static string GetErrorCode(XmlNode errorInfo)
{
XmlNode code = errorInfo.SelectSingleNode("//code");
if (code != null)
return code.InnerText;
else
return "";
}
}
}