原创地址: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。
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。