In our previous blog posts, we have showed you the way for using RetrieveAllEntitiesRequest and RetrieveEntityRequest messages using asynchronous JavaScript for retrieving list of entities for your CRM instance and using it for html Web resource. Now we are going to show you the way for retrieving list of entities via RetrieveAllEntitiesRequest” and attributes through RetrieveEntityRequest” as the specific entity information within C#. Note that you  need to have connection to your CRM organization using appropriate connection data. 


static IOrganizationService _service;
 
static void Main(string[] args)
{
 
ConnectToCRM("CRMUsername", "CRMpassword", "CRMUrl");
Guid userid = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).UserId;
if (userid == Guid.Empty) return; // Check whether connection established or not
Console.WriteLine("Connection successfully established.");
Console.ReadKey();
 
retrieveMetadata(); // using "RetrieveAllEntitiesRequest" and "RetrieveEntityRequest" classes
//retrieveMetadataChanges(); // using "RetrieveMetadataChangesRequest"class
}
 

public static void ConnectToCRM(string UserName, string Password, string SoapOrgServiceUri) { try { ClientCredentials credentials = new ClientCredentials(); credentials.UserName.UserName = UserName; credentials.UserName.Password = Password; Uri serviceUri = new Uri(SoapOrgServiceUri); OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUri, null, credentials, null); proxy.EnableProxyTypes(); _service = (IOrganizationService)proxy; } catch (Exception ex) { Console.WriteLine(“Error while connecting to CRM: ” + ex.Message); } }

By using required filter control, i.e. EntityFilters property, you can control how much data for entity is retrieved. We can use this enumeration with RetrieveAllEntitiesRequest and RetrieveEntityRequest class.

All Use this to retrieve all data for an entity. Value = 15.
Attributes Use this to retrieve entity information plus attributes for the entity. Value = 2.
Default Use this to retrieve only entity information. Equivalent to EntityFilters.Entity. Value = 1.
Entity Use this to retrieve only entity information. Equivalent to EntityFilters.Default. Value = 1.
Privileges Use this to retrieve entity information plus privileges for the entity. Value = 4.
Relationships Use this to retrieve entity information plus entity relationships for the entity. Value = 8.
public static void retrieveMetadata()
{
RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest
{
EntityFilters = EntityFilters.Entity,
RetrieveAsIfPublished = true
};
RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)_service.Execute(request);
 
foreach (EntityMetadata entity in response.EntityMetadata) {
 
RetrieveEntityRequest requestAttribute = new RetrieveEntityRequest {
EntityFilters = EntityFilters.Attributes,
LogicalName = entity.LogicalName,
RetrieveAsIfPublished = true
};
 
RetrieveEntityResponse responseAttributes = (RetrieveEntityResponse)_service.Execute(requestAttribute);
Console.WriteLine(" Attributes Logical Names for: " + entity.LogicalName);
Console.ReadKey();
 
foreach (AttributeMetadata entityAttributes in responseAttributes.EntityMetadata.Attributes)
{
Console.WriteLine(entityAttributes.LogicalName);
}
 
}
Console.WriteLine("Done. ");
Console.ReadKey();
}

But what if you want to filter metadata even further more? For example you only want to get the entities with the property “CanCreateForms” set to true, and their attributes that are only of “AttributeType” equal to Picklist. Unlike “RetrieveAllEntitiesRequest” and “RetrieveEntityRequest”,  “RetrieveMetadataChangesRequest” class contains a Query parameter that accepts an instance of a  “EntityQueryExpression” class. This class has a Criteria property with acceptance of a “MetadataFilterExpression” that contains a collection “MetadataConditionExpression” objects. We will only use one condition to meet the criteria within our example, but you can list more of them and apply And or Or logic between these conditions.

In addition we don’t need to get the list of all the properties during our request/response, we can specify the properties we want with “MetadataPropertiesExpression”, by setting MetadataPropertiesExpression.AllProperties to false, and providing a collection of strings to the MetadataPropertiesExpression.PropertyNames.

public static void retrieveMetadataChanges()
{
// specifying entityFilter to only include entites that CanCreateForms = true
MetadataConditionExpression metadataConditionExpressionEntity = new MetadataConditionExpression();
metadataConditionExpressionEntity.PropertyName = "CanCreateForms";
metadataConditionExpressionEntity.Value = true;
metadataConditionExpressionEntity.ConditionOperator = MetadataConditionOperator.Equals;
MetadataFilterExpression entityFilter = new MetadataFilterExpression();
entityFilter.Conditions.Add(metadataConditionExpressionEntity);
 
// a properties expression to retrieve all properties of Entities
MetadataPropertiesExpression entityProperties = new MetadataPropertiesExpression() {AllProperties = true};
 
//specify attributeFilter to list only attributes that are of AttributeType equal to Picklist
MetadataConditionExpression metadataExpression = new MetadataConditionExpression();
metadataExpression.PropertyName = "AttributeType";
metadataExpression.Value = AttributeTypeCode.Picklist;
metadataExpression.ConditionOperator = MetadataConditionOperator.Equals;
MetadataFilterExpression attributeFilter = new MetadataFilterExpression();
attributeFilter.Conditions.Add(metadataExpression);
 
// a properties expression to limit only DisplayName and AttributeType properties of Attributes
MetadataPropertiesExpression attributeProperties = new MetadataPropertiesExpression() {AllProperties = false};
attributeProperties.PropertyNames.Add("AttributeType");
attributeProperties.PropertyNames.Add("DisplayName");
 
EntityQueryExpression entityQueryExpression = new EntityQueryExpression()
{
Criteria = entityFilter,
Properties = entityProperties,
AttributeQuery = new AttributeQueryExpression() {
Criteria = attributeFilter,
Properties = attributeProperties
}
};
 
RetrieveMetadataChangesRequest requestRetrieveMetadata = new RetrieveMetadataChangesRequest()
{
Query = entityQueryExpression
};
 
RetrieveMetadataChangesResponse responseRetrieveMetadata = (RetrieveMetadataChangesResponse)_service.Execute(requestRetrieveMetadata);
 
foreach (EntityMetadata entityMetadata in responseRetrieveMetadata.EntityMetadata) {
Console.WriteLine(" Attributes Logical Names for: " + entityMetadata.LogicalName);
Console.ReadKey();
 
foreach (AttributeMetadata entityAtt in entityMetadata.Attributes)
{
Console.WriteLine(entityAtt.LogicalName);
}
 
}
Console.WriteLine("Done retrieving MetadataChangesResponse. ");
Console.ReadKey();
}

Hope this post will be useful for making your own queries and retrieving CRM Metadata that you need.