zoukankan      html  css  js  c++  java
  • MS CRM 2011 如何从外部连接CRM

    原创地址:http://www.cnblogs.com/jfzhu/admin/EditPosts.aspx?postid=2752006

    转载请注明出处

    本文要讲解,在CRM应用之外,不具有CRM context的情况下,如何连接到CRM,获得CRM的相关数据。如果你有耐心的话,也可以仔细研究一下SDK中Sample: Simplified Connection Quick Start using Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online。

    CRM 2011提供了一个Assembly microsoft.xrm.client.dll,如果从客户端连接CRM的话,可以使用该Assembly中的OrganizationService类。我在本文中以一个控制台程序来演示如何连接到CRM 2011。首先程序需要使用到的引用如下图。有关CRM的引用都可以在sdk的bin文件夹中找到。

    image

    Program.cs的代码为:

    using System;
    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 ConsoleApplication3
    {
        public class SimplifiedConnection
        {
            #region Class Level Members
            
            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()
            {
                var connection = ConfigurationManager.ConnectionStrings["CrmConnection"];
                return connection.ConnectionString;            
            }
    
    
           
            #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
        }
    }

    上面的程序需要从配置文件读取ConnectionString。一个范例app.config文件如下所示。

    <?xml version="1.0"?>
    <configuration>
      <connectionStrings>
    
        <!-- Online using Office 365 -->
        <!-- <add name="CrmConnection"
             connectionString="Url=https://contoso.crm.dynamics.com; 
             Username=someone@contoso.onmicrosoft.com; 
             Password=password;"/> -->
    
        <!-- Online using Windows Live ID -->
         <add name="CrmConnection"
             connectionString="Url=https://aaronbabbitt.api.crm4.dynamics.com/XRMServices/2011/Organization.svc; 
             Username=username@aaronbabbitt.onmicrosoft.com; Password=password; DeviceID=11hfn41bbqrg580vyvoea05abc; 
             DevicePassword=fuqNIlx%e$.l*+ax_#8O4abc;"/>
    
        <!--On-premises with provided user credentials-->
        <!--<add name="CrmConnection"
             connectionString="Url=http://servername/orgname; Domain=domainname; Username=username; 
             Password=password;"/>-->
    
        <!-- On-premises using Windows integrated security -->
        <!--<add name="CrmConnection"
             connectionString="Url=http://servername/orgname;"/>-->
    
        <!-- On-Premises (IFD) with claims -->
        <!--<add name="CrmConnection"
             connectionString="Url=https://url.xxx/XRMServices/2011/Organization.svc; 
             Username=username@xxx.local; Password=password;"/>-->
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
      </startup>
    </configuration>

    这段代码完成的事情很简单,就是使用OrganizationService类来执行一个WhoAmIRequest。如果成功就表示控制台成功连接到了CRM。配置文件中一共有5个connection string 的样例。分别用来连接:

    (1) 使用Office 365 ID 的 CRM Online;

    (2) 使用Windows Live ID的 CRM Online;

    (3) CRM On-Premises;

    (4)CRM On-Premises,使用当前Windows integrated security来登录,所以不需要提供用户密码;

    (5) 使用了IFD的CRM On-Premises。

    上面除了(1)我没有进行测试,其他四种CRM都通过了该段代码的测试。在Connection String中,对于CRM Online和IFD On-Premises,URL需要使用Organization Service 的 URL。要查看CRM的Organization Service的URL,可以在Settings –> Customization –> Customizations –> Developer Resources中查看

    image

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

    image

    最后再说一下,因为在配置文件中,我们保存了用户登录信息,这样很容易泄露用户名和密码,所以我再说一下如何对配置文件的Connection string进行加密。对配置文件加密可以使用aspnet_regiis.exe工具,Visual Studio自带这个工具。如果没有Visual Studio,.Net中也包含了这个工具。可以在%windows root directory%\Microsoft.NET\%Framework\%version 中找到该工具。首先将app.config另存为文件名为web.config的文件,假如我将该文件保存到我的C:\temp目录中。文件的内容为:

    <?xml version="1.0"?>
    <configuration>
      <connectionStrings>
    
        <!-- Online using Windows Live ID -->
        <add name="CrmConnection"
            connectionString="Url=https://aaronbabbitt.api.crm4.dynamics.com/XRMServices/2011/Organization.svc; 
             Username=username@aaronbabbitt.onmicrosoft.com; Password=password; DeviceID=11hfn41bbqrg580vyvoea05abc; 
             DevicePassword=fuqNIlx%e$.l*+ax_#8O4abc;"/>
       
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
      </startup>
    </configuration>


    运行命令 aspnet_regiis -pef "connectionStrings" "C:\temp",打开web.config文件,发现加密后的内容为:

    <?xml version="1.0"?>
    <configuration>
      <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
          <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
              xmlns="http://www.w3.org/2001/04/xmlenc#">
              <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
              <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                  <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
                      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
                      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                          <KeyName>Rsa Key</KeyName>
                      </KeyInfo>
                      <CipherData>
                          <CipherValue>ll2Y+mC2QlqQ/xhj4jpTu4IQwYVoXjJ7ZVomJvWTtfo5f1o8N46lEPED5Z8k4RrSoJWlk2CKsmxIW8Y5soBlsckEe8ZAGfAHezynUXI1X3QNXLX7qm6F2A7NPuZxpEjKv1JEWOKpTxwo3MMXZwiKjuw3e/puOqKYsrfqT+wHK1E=</CipherValue>
                      </CipherData>
                  </EncryptedKey>
              </KeyInfo>
              <CipherData>
                  <CipherValue>1+ugw1BnAfPhQW3AXtWnjn+KjYFdD4xz56ue8RFjATaNw0HbdyoYm4F+R1zKQP7iqWIebD/gNoYNARFiF7BwHtgOO+7nJsSzkH5i6FgkNaJtvIPUMK7dXF9kCbXEB1MGmnSnjgb8AHhvy68k+Ib1HuWeSvlRDzHuLAOWQ4iM6+Impdcoe27Rs02tRs3a/Jy0NPFhUS+Ps0tTsMJQO5uztcjPbmaNx/jOoxHWaUDWpSx7ucaOK1p/Ko4aN29W1y7iCvvi0wFAOXPi1oega5qSXFnyIADekuPRXxM1vNvKHXBuemxslqtNfazTeY/NxkJ/qRYUbPfdxJRk2MaBZtPOS57nqTWxiRGQJtsUliw4Y0x8sfj/wO0/aDD7T/zFVOj9Ayk15bTNQ2Kpu8qM+DpiUkg/I6l0HDDYz1BZlgItGEjykDjgE6QrB6Woq+svAukEt7bbCitdPPSbliE7d1lxw6VktjQ9/3A1</CipherValue>
              </CipherData>
          </EncryptedData>
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
      </startup>
    </configuration>

    然后你可以将该内容拷贝到你的app.config文件中去。

    解密的命令为aspnet_regiis -pef "connectionStrings" "C:\temp"。当然解密与加密必须是在同一电脑上进行的,如果某个恶意用户获取了你加密后的app.config文件,在他自己的电脑上运行该命令是无法解密该文件的。

    总结:从CRM外部连接CRM,可以使用上面的CRM“万能”连接程序,基本上各种deployment方式的CRM,都可以使用它来连接。该程序使用了Assembly microsoft.xrm.client.dll中的OrganizationService类。你需要在app.config或web.config中配置connection string。最后基于安全性,要对配置文件的connectionStrings section进行加密。加密可以使用aspnet_regiis 工具。

  • 相关阅读:
    初学:利用mybatis-generator自动生成代码
    数组求和forEach方法
    Node.js热部署代码,实现修改代码后自动重启服务方便实时调试
    nodejs中文乱码问题
    简单说一下SS的原理
    Spring Cloud Eureka 3 (Eureka client注册服务提供者)
    Spring Cloud Eureka 2 (Eureka Server搭建服务注册中心)
    Spring Cloud Eureka 1(eureka简介)
    eclipse中创建多模块maven web项目
    eclipse中创建maven web项目
  • 原文地址:https://www.cnblogs.com/jfzhu/p/2752006.html
Copyright © 2011-2022 走看看