Microsoft Dynamics CRM 4.0: C# - Add file to an account

November 23, 2010 by C#  

I recently had the opportunity to do some integration with Microsoft CRM 4.0 (for the first time) for a client - which proved to be quite straightforward.

Microsoft provides a SDK (with tons of examples and documentation) and WebServices (soap based) to aid us with integration etc.

In this post we're going to have a quick look at how to add a file programmatically (using C#) to an account located within CRM.

Step 1: We need to connect/authenticate to CRM.

First of all add a web reference to the crm service e.g. http://cstruter/MSCRMServices/2007/CrmService.asmx".

Observe the following snippet:

CrmService crmService = new CrmService();

void Authenticate()
{
    CrmAuthenticationToken token = new CrmAuthenticationToken();
    token.AuthenticationType = 0;
    token.OrganizationName = "CSTruter";
    crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
    crmService.CrmAuthenticationTokenValue = token;
}

The preceding snippet makes a few assumptions:
  1. That we have/know the organization
  2. Know the location of the WebService for that organization
  3. That we're running in context of an user authenticated against active directory(known as On-premise authentication in CRM)

Now I am not going to go into too much details about authentication in this post, but basically (point 1-2) you'll be able to extract the organization name and webservice url via the CRM discovery service.

With regards to point 3, we could use IFD (internet facing deployment) - for authentication outside the network, or just simple On-premise authentication for users inside our network.

You can read more about it over here:
Web Form (IFD) Authentication
On-Premise Authentication

Step 2: Find the account

BusinessEntity[] GetAccount(string value)
{
	ConditionExpression condition = new ConditionExpression
	{
		AttributeName = "name",
		Operator = ConditionOperator.Equal,
		Values = new object[] { value }
	};

	QueryExpression query = new QueryExpression
	{
		EntityName = "account",
		ColumnSet = new ColumnSet
		{
			Attributes = new string[] { "name", "accountid" }
		},
		Criteria = new FilterExpression
		{
			Conditions = new ConditionExpression[] { condition }
		}
	};

	return crmService.RetrieveMultiple(query).BusinessEntities;
}

In the snippet above we "build" a query in order to retrieve an account that we wish to add a file to. In SQL terms the query would perhaps look something like this:
"SELECT name, acccountid FROM account WHERE name = value"

Step 3: Attach the file

In the following snippet (which should be fairly generic for adding files to objects in CRM), we add a file to our account.
Guid? AddAttachment(string filename, EntityName ObjectType, string ObjectId)
{
    FileInfo fileInfo = new FileInfo(filename);

    if (fileInfo.Exists)
    {
        TargetCreateAnnotation target = new TargetCreateAnnotation
        {
            Annotation = new annotation
            {
                filename = fileInfo.Name,
                isdocument = new CrmBoolean { Value = true },
                documentbody = Convert.ToBase64String(File.ReadAllBytes(filename)),
                mimetype = "application/octet-stream",
                objectid = new Lookup
                {
                    type = "annotation",
                    Value = new Guid(ObjectId)
                },
                objecttypecode = new EntityNameReference { Value = ObjectType.ToString() }
            }
        };

        CreateRequest request = new CreateRequest { Target = target };
        CreateResponse response = (CreateResponse)crmService.Execute(request);
        return response.id;
    }
    return null;
}
Note: rather pass the actual mimetype of the file, than the octet defined in the snippet above

In the final snippet we tie it all together, observe:
static void Main(string[] args)
{
    Authenticate();

    string somedoc = @"c:\6.xls";
    BusinessEntity[] account = GetAccount("dude");
    if (account.Length > 0)
    {
        string accountid = ((account)account[0]).accountid.Value.ToString();
        AddAttachment(somedoc, EntityName.account, accountid);
    }
}

Basically we authenticate and search for an account with the name "dude", if we're able to find it, we attach a file to the first account containing that name (a bit crude, but it gives one the basic idea of how to add a file to an account).

Additional Reading

Microsoft Dynamics CRM 4.0 Software Development Kit (SDK)
AuthenticationType Class (CrmHelpers)
Developing ISV Applications using Microsoft Dynamics CRM 4.0


Leave a Comment