【问题标题】:Error when trying to receive Information from CRM 2011 Webservice尝试从 CRM 2011 Web 服务接收信息时出错
【发布时间】:2013-05-31 01:27:55
【问题描述】:

我在尝试从 Dynamics CRM 2011 检索系统用户信息时收到错误消息。以下代码有效:

public List<CrmUser> GetAllCrmUsers()
{
    List<CrmUser> CrmUsers = new List<CrmUser>();
    using (CrmSdk.OrganizationServiceClient myCrm = new CrmSdk.OrganizationServiceClient("CustomBinding_IOrganizationService1"))
    {
        try
        {

            // this will need to be changed... the address to a key in the app.config and the credentials will need to be whatever is correct for the
            // end server to hit the CRM WCF service
            myCrm.Endpoint.Address = new System.ServiceModel.EndpointAddress("https://devcrm.removed/XRMServices/2011/Organization.svc");
            myCrm.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;


            CrmSdk.ColumnSet colsPrincipal = new CrmSdk.ColumnSet();

            colsPrincipal.Columns = new string[] { "lastname", "firstname", "domainname", "systemuserid" };

            CrmSdk.QueryExpression queryPrincipal = new CrmSdk.QueryExpression();
            queryPrincipal.EntityName = "systemuser";
            queryPrincipal.ColumnSet = colsPrincipal;

            CrmSdk.EntityCollection myAccounts = myCrm.RetrieveMultiple(queryPrincipal);

            foreach (CrmSdk.Entity myEntity in myAccounts.Entities)
            {
                //create new crm users and add it to the list
                CrmUser thisOne = new CrmUser();

                thisOne.firstName = myEntity.Attributes[0].Value.ToString();
                thisOne.lastName = myEntity.Attributes[1].Value.ToString();
                thisOne.userId = myEntity.Attributes[2].Value.ToString();
                thisOne.userGuid = myEntity.Attributes[3].Value.ToString();

                CrmUsers.Add(thisOne);

            }


        }

        catch (Exception ex)
        {
            CrmUser thisOne = new CrmUser();
            thisOne.firstName = "Crap there was an error";
            thisOne.lastName = ex.ToString();
            CrmUsers.Add(thisOne);
        }
    }
    return CrmUsers;
}

但是,如果我在调用服务时尝试将“businessunitid”添加到 ColumnSet,我会收到一条错误消息:

“第 1 行位置 1879 出错。元素 \2004/07/System.Collections.Generic:value\' 包含来自映射到名称 \'/xrm/2011/Contracts:OptionSetValue\' 的类型的数据。解串器不知道映射到此名称的任何类型。请考虑使用 DataContractResolver 或将与 \'OptionSetValue\' 对应的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到列表中传递给 DataContractSerializer 的已知类型。\'"

此错误是因为返回的数据是根据metadata information 的“查找”类型。我尝试在[Data Contract] 标签下添加[KnownType(typeof(OptionSetValue))] 无济于事,我已经用谷歌搜索和Binging(?)这两天了,所以如果它已经得到回答,我很抱歉。

【问题讨论】:

  • 好奇心:您在代码中使用了哪些 CRM 程序集?来自crm 2011 sdk? CrmUser 是自定义类?
  • 是的,CrmUser 是一个自定义类,包含 4 个字符串。名字,姓氏,用户ID,用户Guid。我正在使用 Microsoft.Xrm.Sdk 程序集版本 5.0.0.0。
  • 能否请您指定应用程序的类型(silverlight、Windows 窗体、Web 服务)以及是否在 crm 中作为 webresource 运行 silverlight
  • 可能只需要添加 [KnownTypeAttribute(typeof(EntityReference))] 但我很想知道您为什么要使用这种与 CRM 的连接
  • 我相信您的错误是由 CRM 返回 OptionSetValue 引起的,并且尝试在客户端反序列化它的代码没有对 Microsoft.Xrm.Sdk 的引用,但您已经提到确实如此,所以我有点困惑。

标签: c# wcf dynamics-crm-2011


【解决方案1】:

只需利用Microsoft.Xrm.Client。它为您提供CrmConnection,这是一种连接系统的简化方式。

我还建议(但可能更多的是品味/需求问题)始终通过GetAttributeValue&lt;&gt; 读取属性以获得更易读的代码。

完整的工作示例,包括 BU id:

// helper class
public static class CommonCrm
{        
    public static readonly CrmConnection crmConnection = null;
    public static readonly OrganizationService crmService = null;
    public static readonly CrmOrganizationServiceContext crmContext = null;

    static CommonCrm()
    {
        try
        {
            CommonCrm.crmConnection = new CrmConnection("Crm");

// "Crm" is a connection string which goes like this in Web.config:
//<connectionStrings>
//    <add name="Crm" connectionString="Url=http://orgUrl; Domain=X; Username=Y; Password=Z;" />
//</connectionStrings>

            CommonCrm.crmService = new OrganizationService(crmConnection);
            CommonCrm.crmContext = new CrmOrganizationServiceContext(crmService);
        }
        catch (Exception ex)
        {
            //Log exception (code removed)
            throw;
        }
    }
}

public class CrmUser
{
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string userId { get; set; }
    public Guid userGuid { get; set; }
    public Guid buId { get; set; }

    public static List<CrmUser> GetAllCrmUsers()
    {
        List<CrmUser> CrmUsers = new List<CrmUser>();
        try
        {
            ColumnSet colsPrincipal = new ColumnSet("lastname", "firstname", "domainname", "systemuserid", "businessunitid");
            QueryExpression queryPrincipal = new QueryExpression();
            queryPrincipal.EntityName = "systemuser";
            queryPrincipal.ColumnSet = colsPrincipal;

            var myAccounts = CommonCrm.crmContext.RetrieveMultiple(queryPrincipal);

            foreach (var myEntity in myAccounts.Entities)
            {
                //create new crm users and add it to the list
                CrmUser thisOne = new CrmUser();

                thisOne.firstName = myEntity.GetAttributeValue<string>("firstname");
                thisOne.lastName = myEntity.GetAttributeValue<string>("name");
                thisOne.userId = myEntity.GetAttributeValue<string>("domainname");
                thisOne.userGuid = myEntity.GetAttributeValue<Guid>("systemuserid");
                thisOne.buId = myEntity.GetAttributeValue<EntityReference>("businessunitid").Id;
                // and so on and so forth...         

                CrmUsers.Add(thisOne);
            }
        }
        catch (Exception ex)
        {
            CrmUser thisOne = new CrmUser();
            thisOne.firstName = "Crap there was an error";
            thisOne.lastName = ex.ToString();
            CrmUsers.Add(thisOne);
        }

        return CrmUsers;
    }
}

【讨论】:

  • 他们正在重新加载开发 CRM 服务器,它已经关闭,所以我没有机会尝试你的建议。感谢您的意见,但我一定会在它备份后发布更多内容。
【解决方案2】:

我终于找到了。您必须打开自动生成的 Reference.cs 代码。搜索实体类:

public partial class Entity : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {

转到它上面的行并添加已知类型的东西,以便实体可以对其进行反序列化。

[System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]
public partial class Entity : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {

【讨论】:

  • 我还发现,每次更新或更改服务参考时,您还必须返回并重新添加它。
猜你喜欢
  • 2022-10-04
  • 1970-01-01
  • 2013-03-02
  • 2013-12-29
  • 2014-02-11
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多