Search code examples
c#pluginsdynamics-crm-2016

Entity.Contains(AttributeName) works for all annotation fields but not working for notetext


In following code snippet I am retrieving notes related to an order. It works fine only if notetext does contain data. Now, while debugging I found that, in other case it throws the exception that Object reference not set to an instance of an object.

I think following snippet looks good, but not sure what is missing, any idea to sort out the problem?

private void fetchDocument(IOrganizationService service, Guid vOrderId) 
{
    EntityCollection results = null;
    string tempNote = string.Empty;
    string tempFileName = string.Empty;

    ColumnSet cols = new ColumnSet("subject", "filename", "documentbody", "mimetype","notetext");
    QueryExpression query = new QueryExpression {
            EntityName = "annotation" ,
            ColumnSet = cols,
            Criteria = new FilterExpression
            {
                Conditions = {
                new ConditionExpression("objectid",ConditionOperator.Equal,vOrderId)
            }
            }
            };
    results = service.RetrieveMultiple(query);
    Entity defaultRecord = results.Entities.ElementAtOrDefault(0);

    if(defaultRecord.Contains("notetext"))
    {
        tempNote = defaultRecord.GetAttributeValue<string>("notetext");
    }

    if (defaultRecord.Contains("filename"))
    {
        tempFileName = defaultRecord.GetAttributeValue<string>("filename");
    }       
}

Solution

  • Your issue is actually at this line:

    Entity defaultRecord = results.Entities.ElementAtOrDefault(0);
    

    There are no results found, meaning

    there is no Annotation that exists with an objectid of "vOrderId", or the user that is performing the query, doesn't have rights to read that record.

    Regardless, you should just check for defaultRecord being null or not, and exiting if it is.

    This check of null is a common occurrence, which is why I've written this ExtensionMethod:

    public Entity GetFirstOrDefault(this IOrganizationService service, QueryBase qb) {
        return service.RetrieveMultiple(qb)?.Entities.FirstOrDefault();
    }
    

    This would simplify your code to this:

    private void fetchDocument(IOrganizationService service, Guid vOrderId) 
    {
        EntityCollection results = null;
        string tempNote = string.Empty;
        string tempFileName = string.Empty;
    
        ColumnSet cols = new ColumnSet("subject", "filename", "documentbody", "mimetype","notetext");
        QueryExpression query = new QueryExpression {
                EntityName = "annotation" ,
                ColumnSet = cols,
                Criteria = new FilterExpression
                {
                    Conditions = {
                    new ConditionExpression("objectid",ConditionOperator.Equal,vOrderId)
                }
                }
                };
    
        var defaultRecord = service.GetFirstOrDefault(query);
        if(defaultRecord != null)
        {
            if(defaultRecord.Contains("notetext"))
            {
                 tempNote = defaultRecord.GetAttributeValue<string>("notetext");
            }
    
            if (defaultRecord.Contains("filename"))
            {
                tempFileName = defaultRecord.GetAttributeValue<string>("filename");
            } 
        }
    }