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。
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。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构