1

我需要通过 CRM 365 插件连接和检索 CRM Online 中的记录。我尝试过使用简化连接,xrm.tooling.dll但不幸的是它说Could not load file or assembly 'microsoft.xrm.tooling.connector,当我使用ClientCredential错误时说Metadata contain refereces that cannot be resolved

奇怪的是,我用控制台应用程序尝试了这两种方法,而且效果很好。只是想知道我在这种情况下想念什么?当我想通过插件连接到CRM时,我需要特殊要求吗?请任何人分享您的知识。

编辑

这只是从 CRM Online 获取帐户名称并使用 InvalidPluginExecutionException 显示它的示例代码:

IOrganizationService _service;

public void Execute(IServiceProvider serviceprovider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = servicefactory.CreateOrganizationService(context.UserId);

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
           {

                Entity ent = (Entity)context.InputParameters["Target"];

                if (ent.LogicalName != "opportunity")
                    return;

                string connstring = @"Url=https://office.crm5.dynamics.com; Username=username@office.onmicrosoft.com; Password=crmoffice; authtype=Office365";
                CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connstring);
                service = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : 

(IOrganizationService)conn.OrganizationServiceProxy;


                try
                {
                    Guid fabercastel = new Guid("efd566dc-10ff-e511-80df-c4346bdcddc1");
                    Entity _account = new Entity("account");
                    _account = service.Retrieve(_account.LogicalName, fabercastel, new ColumnSet("name"));

                    string x = _account["name"].ToString();


                    throw new InvalidPluginExecutionException("Result of Query : " + x);
                }
                catch (Exception ex)
                {
                    throw new InvalidPluginExecutionException(ex.Message);
                }
4

4 回答 4

2

您已经使用您在插件第三行定义的 IOrganizationService 连接到 CRM。除非您需要连接到不同组织中的另一个 CRM 实例,否则不需要或不需要登录。

基本上只需删除您尝试上方的 4 行,您应该会很好。

编辑:

public void Execute(IServiceProvider serviceprovider)
{
    IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext));
    IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory));
    IOrganizationService service = servicefactory.CreateOrganizationService(context.UserId);

    if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
    {

         Entity ent = (Entity)context.InputParameters["Target"];

         if (ent.LogicalName != "opportunity")
             return;

         Guid fabercastel = new Guid("efd566dc-10ff-e511-80df-c4346bdcddc1");
         Entity _account = new Entity("account");
         _account = service.Retrieve(_account.LogicalName, fabercastel, new ColumnSet("name"));

         string x = _account["name"].ToString();


         throw new InvalidPluginExecutionException("Result of Query : " + x);
    }
}
于 2017-02-20T11:25:04.257 回答
2

您不需要任何额外的库,如 Microsoft.Xrm.Tooling.Connector 或 SDK 中的其他库来使用 CRM Web 服务。与 SOAP / REST 协议相关的标准 .NET 机制就足够了(当然这种方法可能稍微困难一些)。

编辑:我进行了一些额外的调查,发现在不使用 SDK 库的情况下为 Office365 身份验证配置自动生成的 OrganizationServiceClient 可能真的很痛苦。我不是说这是不可能的,但是微软没有记录它。添加更多详细信息 Visual Studio 生成的代理类不支持 OAuth 身份验证。

因此,我的第二个建议是使用外观 Web 服务与 CRM OnLine 进行通信。您可以在 Windows Azure 或 Internet 中的任何其他云/托管位置托管此 Web 服务。通过您的 CRM 365 插件,您可以使用您的自定义 Web 服务方法并使用此服务与您的 CRM Online 实例进行通信。我想尝试运行未记录的连接到 CRM Online 的方法会更好。**

于 2017-02-21T07:05:40.973 回答
2

您应该能够连接到另一个 CRM 实例,而无需使用 Online Sandbox 之外的任何程序集(Microsoft.Xrm.Sdk 和相关程序除外)。只需使用来自“SDK\SampleCode\CS\GeneralProgramming\Authentication\AuthenticateWithNoHelp\AuthenticateWithNoHelp.cs”的 SDK 示例。连接 Office365 的简化版如下所示:

class AuthenticateWithNoHelp
{
    private String _discoveryServiceAddress = "https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc";
    private String _organizationUniqueName = "orgname";
    private String _userName = "admin@orgname.onmicrosoft.com";
    private String _password = "password";
    private String _domain = "domain";

    public void Run()
    {
        IServiceManagement<IDiscoveryService> serviceManagement =
                    ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(
                    new Uri(_discoveryServiceAddress));
        AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;

        AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType);


        String organizationUri = String.Empty;
        using (DiscoveryServiceProxy discoveryProxy =
            GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
        {
            if (discoveryProxy != null)
            {
                OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
                organizationUri = FindOrganization(_organizationUniqueName,
                    orgs.ToArray()).Endpoints[EndpointType.OrganizationService];

            }
        }

        if (!String.IsNullOrWhiteSpace(organizationUri))
        {
            IServiceManagement<IOrganizationService> orgServiceManagement =
                ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
                new Uri(organizationUri));

            AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType);

            using (OrganizationServiceProxy organizationProxy =
                GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
            {
                organizationProxy.EnableProxyTypes();
                Guid userid = ((WhoAmIResponse)organizationProxy.Execute(
                    new WhoAmIRequest())).UserId;
            }
        }
    }

    private AuthenticationCredentials GetCredentials<TService>(IServiceManagement<TService> service, AuthenticationProviderType endpointType)
    {
        AuthenticationCredentials authCredentials = new AuthenticationCredentials();

        authCredentials.ClientCredentials.UserName.UserName = _userName;
        authCredentials.ClientCredentials.UserName.Password = _password;

        return authCredentials;
    }

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

        return orgResponse.Details;
    }

    public 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.UrlName, orgUniqueName,
                StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                orgDetail = detail;
                break;
            }
        }
        return orgDetail;
    }

    private 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);
            return (TProxy)classType
                .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) })
                .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
        }

        return (TProxy)classType
            .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(ClientCredentials) })
            .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
    }

    static public void Main(string[] args)
    {
        AuthenticateWithNoHelp app = new AuthenticateWithNoHelp();
        app.Run();
    }
}

您可以通过使用 DiscoveryService 删除部分并直接调用来进一步简化它:

https://orgname.api.crm.dynamics.com/XRMServices/2011/Organization.svc

这应该适用于沙盒插件,因为它仅使用 Sdk 程序集。

于 2017-03-18T11:18:01.853 回答
0

您应该能够连接到另一个 CRM 实例,而无需使用 Online Sandbox 之外的任何程序集(除Microsoft.Xrm.Sdk相关之外)。

例如,只需使用来自 SDK 的示例SDK\SampleCode\CS\GeneralProgramming\Authentication\AuthenticateWithNoHelp\AuthenticateWithNoHelp.cs

于 2020-12-14T06:06:15.987 回答