尝试从CRM 2011 Webservice接收信息时出错
本文关键字:信息 出错 Webservice CRM 2011 | 更新日期: 2023-09-27 18:17:05
在尝试从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。泛型:value''包含映射到名称''/xrm/2011/Contracts:OptionSetValue''的类型的数据。反序列化程序不知道映射到该名称的任何类型。考虑使用DataContractResolver或将与'OptionSetValue '相对应的类型添加到已知类型列表中-例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表中。
此错误是因为根据元数据信息返回的数据类型为"Lookup"。我试着在[Data Contract]
标签下添加[KnownType(typeof(OptionSetValue))]
,但无济于事,我已经在谷歌和bing搜索了两天了,所以如果它已经得到了回答,我道歉。
利用Microsoft.Xrm.Client
。它为您提供了CrmConnection
,这是一种连接到系统的简化方式。
我还建议(但这可能更多的是品味/需要的问题)总是通过GetAttributeValue<>
读取属性,以获得更可读的代码。
完整的工作样本,包括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;
}
}
我终于找到了。您必须打开自动生成的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 {