读书人

MS CRM 万能联接

发布时间: 2012-09-13 09:51:53 作者: rapoo

MS CRM 万能连接

SDK中有一个例子叫” Sample: Simplified Connection Quick Start using Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online”。这个例子演示了如何连接 CRM On-premises, CRM On-premises IFD, 以及 CRM Online。我觉得还不够简化,下面我演示一个更简化的版本,而且我们只执行一个WhoAmIRequest的请求,和一个Retrieve的请求。

在看代码之前,我首先发现了sdk的例子中有一个问题,在配置文件中,对于CRM Online和CRM IFD的connection string,URL的部分单单写出server name是不够的,应该写Organization Service的URL。

首先看配置文件,在配制文件中我们使用connection string,它配置起来很简单,而且最大的好处是还可以加密。

<?xml version="1.0"?><configuration>  <connectionStrings>    <!-- Online using Office 365 -->    <!-- <add name="Server=CRM Online, organization=contoso, user=someone"         connectionString="Url=https://contoso.crm.dynamics.com;          Username=someone@contoso.onmicrosoft.com;          Password=password;"/> -->    <!-- Online using Windows Live ID -->    <!-- <add name="Server=CRM Online, organization=contoso, user=someone@hotmail.com"         connectionString="Url=https://rmibv.api.crm4.dynamics.com/XRMServices/2011/Organization.svc;          Username=someone@hotmail.com; Password=password; DeviceID=11hfn41bbqrg580vyvoea05abc;          DevicePassword=fuqNIlx%e$.l*+ax_#8O4abc;"/>-->    <!--On-premises with provided user credentials-->    <!--<add name="Server=nlbesawse21, organization=vdl, user=administrator"         connectionString="Url=http://myserver/AdventureWorksCycle; Domain=domainName; Username=userName;          Password=password;"/>-->    <!-- On-premises using Windows integrated security -->    <!--<add name="Server=myserver, organization=AdventureWorksCycle"         connectionString="Url=http://myserver/AdventureWorksCycle;"/>-->    <!-- On-Premises (IFD) with claims -->    <!--<add name="Server=litware.com, organization=contoso, user=someone@litware.com"         connectionString="Url=https://abc.abc.com/XRMServices/2011/Organization.svc;          Username=someone@litware.com; Password=password;"/>-->  </connectionStrings>  <startup>    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>  </startup></configuration>

以下是连接程序的代码,连接不同的CRM只需要更改配置文件,不需要更改任何代码

using System;using System.Collections.Generic;using Microsoft.Xrm.Client.Services;using Microsoft.Xrm.Client;using Microsoft.Crm.Sdk.Messages;using System.ServiceModel;using System.Configuration;using Microsoft.Xrm.Sdk;using Microsoft.Xrm.Sdk.Query;namespace SimpleConnection{    public class SimplifiedConnection    {        #region Class Level Members        private Guid _accountId;        private OrganizationService _orgService;        #endregion Class Level Members        public void Run(String connectionString, bool promptforDelete)        {            try            {                // Establish a connection to the organization web service using CrmConnection.                Microsoft.Xrm.Client.CrmConnection connection = CrmConnection.Parse(connectionString);                // Obtain an organization service proxy.                // The using statement assures that the service proxy will be properly disposed.                using (_orgService = new OrganizationService(connection))                {                                       // Obtain information about the logged on user from the web service.                    Guid userid = ((WhoAmIResponse)_orgService.Execute(new WhoAmIRequest())).UserId;                    Entity systemUser = _orgService.Retrieve("systemuser", userid,                         new ColumnSet(new string[] { "firstname", "lastname" }));                    Console.WriteLine("Logged on user is {0} {1}.",                         systemUser["firstname"].ToString(), systemUser["lastname"].ToString());                                    }            }            // Catch any service fault exceptions that Microsoft Dynamics CRM throws.            catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)            {                // You can handle an exception here or pass it back to the calling method.                throw;            }        }        #region Public Methods               #endregion Public Methods        #region Private Methods        /// <summary>        /// Gets web service connection information from the app.config file.        /// If there is more than one available, the user is prompted to select        /// the desired connection configuration by name.        /// </summary>        /// <returns>A string containing web service connection configuration information.</returns>        private static String GetServiceConfiguration()        {            // Get available connection strings from app.config.            int count = ConfigurationManager.ConnectionStrings.Count;            // Create a filter list of connection strings so that we have a list of valid            // connection strings for Microsoft Dynamics CRM only.            List<KeyValuePair<String, String>> filteredConnectionStrings =                new List<KeyValuePair<String, String>>();            for (int a = 0; a < count; a++)            {                if (isValidConnectionString(ConfigurationManager.ConnectionStrings[a].ConnectionString))                    filteredConnectionStrings.Add                        (new KeyValuePair<string, string>                            (ConfigurationManager.ConnectionStrings[a].Name,                            ConfigurationManager.ConnectionStrings[a].ConnectionString));            }            // No valid connections strings found. Write out and error message.            if (filteredConnectionStrings.Count == 0)            {                Console.WriteLine("An app.config file containing at least one valid Microsoft Dynamics CRM " +                    "connection string configuration must exist in the run-time folder.");                Console.WriteLine("\nThere are several commented out example connection strings in " +                    "the provided app.config file. Uncomment one of them and modify the string according " +                    "to your Microsoft Dynamics CRM installation. Then re-run the sample.");                return null;            }            // If one valid connection string is found, use that.            if (filteredConnectionStrings.Count == 1)            {                return filteredConnectionStrings[0].Value;            }            // If more than one valid connection string is found, let the user decide which to use.            if (filteredConnectionStrings.Count > 1)            {                Console.WriteLine("The following connections are available:");                Console.WriteLine("------------------------------------------------");                for (int i = 0; i < filteredConnectionStrings.Count; i++)                {                    Console.Write("\n({0}) {1}\t",                    i + 1, filteredConnectionStrings[i].Key);                }                Console.WriteLine();                Console.Write("\nType the number of the connection to use (1-{0}) [{0}] : ",                    filteredConnectionStrings.Count);                String input = Console.ReadLine();                int configNumber;                if (input == String.Empty) input = filteredConnectionStrings.Count.ToString();                if (!Int32.TryParse(input, out configNumber) || configNumber > count ||                    configNumber == 0)                {                    Console.WriteLine("Option not valid.");                    return null;                }                return filteredConnectionStrings[configNumber - 1].Value;            }            return null;        }        /// <summary>        /// Verifies if a connection string is valid for Microsoft Dynamics CRM.        /// </summary>        /// <returns>True for a valid string, otherwise False.</returns>        private static Boolean isValidConnectionString(String connectionString)        {            // At a minimum, a connection string must contain one of these arguments.            if (connectionString.Contains("Url=") ||                connectionString.Contains("Server=") ||                connectionString.Contains("ServiceUri="))                return true;            return false;        }        #endregion Private Methods        #region Main method        /// <summary>        /// Standard Main() method used by most SDK samples.        /// </summary>        /// <param name="args"></param>        static public void Main(string[] args)        {            try            {                // Obtain connection configuration information for the Microsoft Dynamics                // CRM organization web service.                String connectionString = GetServiceConfiguration();                if (connectionString != null)                {                    SimplifiedConnection app = new SimplifiedConnection();                    app.Run(connectionString, true);                }            }            catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)            {                Console.WriteLine("The application terminated with an error.");                Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp);                Console.WriteLine("Code: {0}", ex.Detail.ErrorCode);                Console.WriteLine("Message: {0}", ex.Detail.Message);                Console.WriteLine("Trace: {0}", ex.Detail.TraceText);                Console.WriteLine("Inner Fault: {0}",                    null == ex.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");            }            catch (System.TimeoutException ex)            {                Console.WriteLine("The application terminated with an error.");                Console.WriteLine("Message: {0}", ex.Message);                Console.WriteLine("Stack Trace: {0}", ex.StackTrace);                Console.WriteLine("Inner Fault: {0}",                    null == ex.InnerException.Message ? "Has Inner Fault" : "No Inner Fault");            }            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);                    FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException                        as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;                    if (fe != null)                    {                        Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp);                        Console.WriteLine("Code: {0}", fe.Detail.ErrorCode);                        Console.WriteLine("Message: {0}", fe.Detail.Message);                        Console.WriteLine("Trace: {0}", fe.Detail.TraceText);                        Console.WriteLine("Inner Fault: {0}",                            null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");                    }                }            }            // Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException,            // SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException.            finally            {                Console.WriteLine("Press <Enter> to exit.");                Console.ReadLine();            }        }        #endregion Main method    }}


最后再说一下,连接CRM Online的时候,需要DeviceID和DevicePassword。很多人不懂DeviceID是干什么用的。DeviceID的目的就是注册一个设备,使这个设备可以使用Windows Live ID。当你注册了这个设备后,任何用户就都可以使用这个设备了。所以如果这个是一个从未注册过的设备,你首先要注册它。关于如何注册一个设备,可以使用sdk带的deviceregistration工具。具体的命令是DeviceRegistration.exe /operation:Register。命令运行成功后,你就可以拷贝生成的Device ID和Device Password了。

读书人网 >互联网

热点推荐