Finding Shared CRM Accounts, Part 2

On December 6, 2006, in Customization, Dynamics CRM, by Mitch Milam

I just love the CRM community.  Ayaz Ahmad posted a comment on the previous article about finding Shared CRM Accounts and included a C# function written to perform a similar function to the SQL code in the other article. 

Ayaz's version uses the CRM SDK to retrieve all of the accounts for a specified Team instead of performing a SQL query.  This will allow you to add it to an application without having to resort to performing direct SQL Queries. 

This the example will place the Account Names into a ListView and is used like this:

// This is the Guid from the Everyone Team on my development
// system. You will need to substitute a real Guid from
// your system to make this function correctly.
Guid TeamID = new Guid("3146CAE5-B13E-DB11-ADAF-00142A05B544");
ListSharedObjectByTeams(TeamID);

 

and here is the function that does all of the work.

void ListSharedObjectByTeams(Guid TeamId)
{
    try
    {
	CrmService service = new CrmService();
	service.Credentials = System.Net.CredentialCache.DefaultCredentials;

	// Create the ColumnSet indicating the fields to be retrieved
	ColumnSet cols = new ColumnSet();

	// Sets the ColumnSet's Properties
	cols.Attributes = new string [] {"name", "accountid"};

	// Create the QueryExpression Object
	QueryExpression query = new QueryExpression();

	// Set the QueryExpression Object's Properties
	query.EntityName = EntityName.account.ToString();
	query.ColumnSet = cols;

	// Retrieve the Contacts
	BusinessEntityCollection bus = service.RetrieveMultiple(query);
	for (int i = 0; i<bus.BusinessEntities.Length; i++)
	{
		account acct = (account)bus.BusinessEntities[i];

		TargetOwnedDynamic target = new TargetOwnedDynamic();
		target.EntityId = acct.accountid.Value;
		target.EntityName = EntityName.account.ToString();

		// Get Shared Access Rights
		RetrieveSharedPrincipalsAndAccessRequest access = new
		RetrieveSharedPrincipalsAndAccessRequest();
		access.Target = target;

		RetrieveSharedPrincipalsAndAccessResponse accessResponse =
		(RetrieveSharedPrincipalsAndAccessResponse)
                     service.Execute(access);
		foreach (PrincipalAccess principalAccess in
			accessResponse.PrincipalAccesses)
		{
		     switch (principalAccess.Principal.Type)
		     {
			case SecurityPrincipalType.Team:
			    if (principalAccess.Principal.PrincipalId
                                     == TeamId)
			    {
                                     // Add the Account Name to the ListView
				listAvailable.Items.Add(acct.name);
			    }
			break;
		    }
		}
	}
     }
     catch(Exception ex)
     {
	throw(ex);
     }
}

Thanks for sharing Ayaz.

 

By the way, Ayaz is a big part of the Microsoft CRM Pakistan User Group.

MSCRMPUG (Microsoft CRM Pakistan User Group) is an INETA chartered user group, a Microsoft Dynamics Related Community, Culminis ALLIANCE and O'Reilly User Group Professional Association. This group is set up in mind of the growing numbers of Microsoft Dynamics CRM (pronounced as Customer Relationship Management) users in Pakistan. It provides members with the base for communicating with each other to share ideas and exchange contacts as well as helping each other in development work and to discuss technical issue regarding implementation, customization, Development and extending MSCRM in small and medium businesses. A group open to all users, administrators, developers and consultants working with Microsoft Dynamics CRM (Customer Relationship Management).

 

CRM, ISVReadiness, and XML Parsing

On December 6, 2006, in Customization, Dynamics CRM, by Mitch Milam

Morning Everyone,

This may be way to deep-geek for most of you, but I ran into something this morning that may be of interest to those of you who work with CRM's XML config files.

I was extending the IsvConfigCustomizer code that ships as part of the ISVReadiness sample code from the CRM SDK to iterate through the Entities section of the ISV.Config file to pull the names of CRM Entities that have had ISV customizations added.

The XML looks like this:

    <Entity name="campaignactivity" />
    <Entity name="campaignresponse" />
    <Entity name="incident" />
    <!-- Case -->
    <Entity name="quote" />
    <Entity name="salesorder" />
    <!-- Order -->

Everything worked fine, until I hit that comment line containing the word Case.  Since it is a comment, it has no attributes. Since I am looking for an attribute called name, my code was failing.

Luckily, the .NET XmlNode class has a corresponding XmlNodeType property that allows me to see if I have encountered a comment or not.  The following code ensures I have not encountered a comment before I add the Entity name to my array:

 

XmlNode docRoot = GetConfigurationNode().SelectSingleNode("Entities");

int iCount = docRoot.ChildNodes.Count;

ArrayList sArray = new ArrayList();
for(int i = 0; i < iCount; i++)
{
	if (docRoot.ChildNodes[i].NodeType != XmlNodeType.Comment)
	{
		XmlAttribute xAttrib = docRoot.ChildNodes[i].Attributes["name"];

		if xAttrib!= null)
		{
			sArray.Add(xAttrib.InnerText);
		}
	}
}