MS CRM 2011 如何从外部连接CRM 二

 

原创地址:http://www.cnblogs.com/jfzhu/archive/2013/02/28/2937936.html

转载请注明出处

 

我在以前的文章中介绍过如何使用OrganizationService类来连接CRM的Web Service,在本文中我将介绍如何使用OrganizationServiceProxy类来连接CRM的Web Service。

 

Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy类与 Microsoft.Xrm.Client.Services.OrganizationService类的区别在于,前者既然叫做Proxy,通常是在CRM的Context之外使用,而后者是在CRM的Context中使用的。另外一个区别是如果你想impersonate为其他人的话,就只能使用OrganizationServiceProxy(CallerId )。

 

我在本文中创建一个console程序,通过OrganizationServiceProxy来使用CRM的Web Service,并通过设置OrganizationServiceProxy的CallerId 来代表别人创建一个 lead。顺便说一下,想要Impersonate别人的用户必须在CRM中具有Act on Behalf of Aonther User的权限,或者在Active Directory中加入PrivUserGroup。

image

 

using System; 
using Microsoft.Xrm.Sdk.Discovery; 
using Microsoft.Xrm.Sdk.Client; 
using System.Configuration; 
using Microsoft.Xrm.Sdk; 
using Microsoft.Crm.Sdk.Messages;

namespace ConsoleApplication3 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            string _discoveryServiceAddress = ConfigurationManager.AppSettings["DiscoveryServiceAddress"]; 
            IServiceManagement<IDiscoveryService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(new Uri(_discoveryServiceAddress)); 
            AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;

            AuthenticationCredentials authCredentials = GetCredentials(endpointType);

            //String organizationUri = String.Empty; 
            //string organizationUniqueName = ConfigurationManager.AppSettings["OrganizationUniqueName"]; 
            //// Get the discovery service proxy. 
            //using (DiscoveryServiceProxy discoveryProxy = GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials)) 
            //{ 
            //    // Obtain organization information from the Discovery service. 
            //    if (discoveryProxy != null) 
            //    { 
            //        // Obtain information about the organizations that the system user belongs to. 
            //        OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy); 
            //        // Obtains the Web address (Uri) of the target organization. 
            //        organizationUri = FindOrganization(organizationUniqueName, orgs.ToArray()).Endpoints[EndpointType.OrganizationService]; 
            //    } 
            //}

            String organizationUri = ConfigurationManager.AppSettings["OrganizationServiceAddress"]; 
            if (!String.IsNullOrWhiteSpace(organizationUri)) 
            { 
                IServiceManagement<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri));

                // Set the credentials. 
                AuthenticationCredentials credentials = GetCredentials(endpointType);

                // Get the organization service proxy. 
                using (OrganizationServiceProxy organizationProxy = GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials)) 
                { 
                    // This statement is required to enable early-bound type support. 
                    organizationProxy.EnableProxyTypes(); 
                    organizationProxy.CallerId = new Guid("D63C171E-F47C-E211-A79A-00155DA83B36");

                    // Now make an SDK call with the organization service proxy. 
                    // Display information about the logged on user. 
                    Guid userid = ((WhoAmIResponse)organizationProxy.Execute(new WhoAmIRequest())).UserId; 
                    Entity systemUser = organizationProxy.Retrieve("systemuser", userid, new Microsoft.Xrm.Sdk.Query.ColumnSet(new string[] { "firstname", "lastname" }));

                    Entity newEntity = new Entity("lead"); 
                    
                    newEntity["salutation"] = "test"; 
                    newEntity["middlename"] = "test"; ; 
                    newEntity["lastname"] = "test"; ; 
                    newEntity["jobtitle"] = "test"; ;

                    organizationProxy.Create(newEntity);        
                } 
            }

        }

        private static AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType) 
        { 
            string _userName = ConfigurationManager.AppSettings["UserName"]; 
            string _password = ConfigurationManager.AppSettings["Password"]; 
            string _domain = ConfigurationManager.AppSettings["Domain"];

            AuthenticationCredentials authCredentials = new AuthenticationCredentials(); 
            switch (endpointType) 
            { 
                case AuthenticationProviderType.ActiveDirectory: 
                    authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(_userName, _password, _domain); 
                    break; 
                case AuthenticationProviderType.Federation: 
                case AuthenticationProviderType.OnlineFederation: 
                    authCredentials.ClientCredentials.UserName.UserName = _userName; 
                    authCredentials.ClientCredentials.UserName.Password = _password; 
                    break; 
                default:                     
                    break; 
            }

            return authCredentials; 
        }

        private static TProxy GetProxy<TService, TProxy>(IServiceManagement<TService> serviceManagement, AuthenticationCredentials authCredentials) 
            where TService : class 
            where TProxy : ServiceProxy<TService> 
        { 
            Type classType = typeof(TProxy);

            if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory) 
            { 
                AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials); 
                // Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. 
                // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse. 
                return (TProxy)classType 
                    .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) }) 
                    .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse }); 
            }

            // Obtain discovery/organization service proxy for ActiveDirectory environment. 
            // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials. 
            return (TProxy)classType 
                .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(System.ServiceModel.Description.ClientCredentials) }) 
                .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials }); 
        }

        private static OrganizationDetailCollection DiscoverOrganizations(IDiscoveryService service) 
        { 
            if (service == null) 
                throw new ArgumentNullException("service"); 
            RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest(); 
            RetrieveOrganizationsResponse orgResponse = (RetrieveOrganizationsResponse)service.Execute(orgRequest);

            return orgResponse.Details; 
        }

        private static OrganizationDetail FindOrganization(string orgUniqueName, OrganizationDetail[] orgDetails) 
        { 
            if (String.IsNullOrWhiteSpace(orgUniqueName)) 
                throw new ArgumentNullException("orgUniqueName"); 
            if (orgDetails == null) 
                throw new ArgumentNullException("orgDetails"); 
            OrganizationDetail orgDetail = null;

            foreach (OrganizationDetail detail in orgDetails) 
            { 
                if (String.Compare(detail.UniqueName, orgUniqueName, 
                    StringComparison.InvariantCultureIgnoreCase) == 0) 
                { 
                    orgDetail = detail; 
                    break; 
                } 
            } 
            return orgDetail; 
        } 
    } 
}

 

配置文件:

<?xml version="1.0"?> 
<configuration> 
  <appSettings> 
    <!-- On-premises using Windows integrated security --> 
    <!--<add key="DiscoveryServiceAddress" value="http://servername/XRMServices/2011/Discovery.svc"/> 
    <add key="UserName" value="username"/> 
    <add key="Password" value="password"/> 
    <add key="Domain" value="domain"/> 
    <add key="OrganizationUniqueName" value="orgname"/> 
    <add key="OrganizationServiceAddress" value="http://servername/orgname/XRMServices/2011/Organization.svc"/>-->

    <!-- On-Premises (IFD) with claims --> 
    <!--<add key="DiscoveryServiceAddress" value="https://test/XRMServices/2011/Discovery.svc"/> 
    <add key="UserName" value="username@test.local"/> 
    <add key="Password" value="password"/> 
    <add key="Domain" value=""/> 
    <add key="OrganizationUniqueName" value="orgname"/> 
    <add key="OrganizationServiceAddress" value="https://test/XRMServices/2011/Organization.svc"/>-->

    <!-- Online using Office 365 --> 
    <add key="DiscoveryServiceAddress" value="https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc"/> 
    <add key="UserName" value="username@test.onmicrosoft.com"/> 
    <add key="Password" value="password"/> 
    <add key="Domain" value=""/> 
    <add key="OrganizationUniqueName" value="orgname"/> 
    <add key="OrganizationServiceAddress" value="https://test.api.crm4.dynamics.com/XRMServices/2011/Organization.svc"/> 
  </appSettings> 
  <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
  </startup> 
</configuration>

 

如果是使用On-Premise CRM,AuthenticationType 是ActiveDirectory;如果使用的是IFD On-Premise CRM,AuthenticationType 是Federation;如果是CRM Online,AuthenticationType 是OnlineFederation。

 

当使用IFD-CRM或者CRM Online的时候,不需要在configuration中填写domain,但username要使用UPN name,查看用户UPN name可以使用命令 whoami /upn

 

通过上面的代码创建的lead,你会发现createdby和modifiedby都是CallerId所指定的用户。

 

 

总结: 使用OrganizationServiceProxy类可以连接CRM的Web service。通过设置CallerId 可以Impersonate。

posted @ 2013-02-28 23:25  Coding十日谈  阅读(2065)  评论(0编辑  收藏