Saturday, October 3, 2009

MS CRM 4.0 Sending Attachments to the Browser

In a previous blog article I covered how to take files and make them attachments to emails. Creating Attachments to emails and annotations 

Recently I’ve been spending more time building portals to MS CRM, and have needed to make attached files available to the user by browser.

From a custom web app running with MS CRM you can always create a link like the following that will call the annotation editor screen which will let you download the attachment or delete it or add an additional attachment to the annotation.

string link = String.Format(@"{0}{1}/notes/edit.aspx?id={2}", crmServerBaseUrl, orgname, thisNote.annotationid.Value);

However sometimes when working with an external application you don’t have the ability to call the MS CRM functionality or for aesthetic reasons you want things to look differently. In this case I have a Silverlight 3 application with a completely different look and feel and I just need to retrieve annotation attachments from a list associated with an entity or contact. The ExportFile() method below would work just as well with an activitymimeattachment for email attachments.

The following aspx file simply takes an annotationid querystring, retrieves that annotation ( you provide the query) and sends the attached file to the user’s browser. The user will then be able to download the file or open the file in an appropriate application.

using System;
using System.Web;
using Passport.Web.Services.Logic;

namespace YourProject
    public partial class SendAnnotation : System.Web.UI.Page
        protected void Page_Load(object sender, EventArgs e)
            if (Request.QueryString["id"] != null)
                Guid annotationId = new Guid(Request.QueryString["id"].Replace("{", "").Replace("}", ""));

                // Get annotation
                annotation fileContainer = // fill in the query logic you need here.
                // Call method to write
                ExportFile(fileContainer.filename, fileContainer.documentbody, fileContainer.mimetype);             

        /// <summary>
        /// This method takes the annotation documentbody and writes it back to the browser
        /// with a file name and mimetype so that your browser knows how to intelligently 
        /// handle the file being sent to it.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="content"></param>
        /// <param name="type"></param>
        private void ExportFile(string fileName, string content, string type)
            byte[] fileContent = Convert.FromBase64String(content);
            Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
            Response.ContentType = type;