As of April 17, 2018, this site is now in read-only mode. To start new Blackbaud Developer’s discussions, you will find Developer Discussions in the Blackbaud CRM Community.

To post or respond to Blackbaud Community discussions, you will have to login using a login. Learn how to login here. If you have questions or need assistance, please email

Download a file to the user’s browser via CRM

By: Chris Whisenhunt

Posted on: December 1, 2016

To download a custom file in CRM using VB you need to create a class that inherits Blackbaud.AppFx.Server.AppCatalog.AppCustomFileDownloadProcess like so.

Imports Blackbaud.AppFx.Server
Imports System.IO

Public Class TestFileDownloadHandler
    Inherits AppCatalog.AppCustomFileDownLoadProcessor

    Public Overrides Function CheckSecurity() As SecurityCheckResult
        Return SecurityCheckResult.SecurityCheckPassed
    End Function

    Public Overrides Sub ValidateArgs()
        If String.IsNullOrEmpty(Me.RequestArgs.Parameters("Text")) Then
            Throw New Exception("Text parameter not provided")
        End If
    End Sub

    Public Overrides Function PopulateStream(stream As Stream) As AppCatalog.AppCustomFileDownloadResult
        Dim result = New AppCatalog.AppCustomFileDownloadResult
        result.DataLoaded = False

        If stream Is Nothing Then
            Return result
        End If

        Me.RequestContext.HTTPContext.Response.AddHeader("content-disposition", "attachment; filename=""test.txt""")

        Dim text = Me.RequestArgs.Parameters("text")

        Using streamWriter As New StreamWriter(stream)
        End Using

        result.DataLoaded = True

        Return result
    End Function
End Class

As you can see it’s pretty straight forward. You can pass in any number of arguments you want, like a record ID, etc. Then you would just build out the stream.

Now to actually get the file is a little different. It is actually served up by a file handler.


The customfiledownload.ashx takes in a few parameters itself.

DBName = BBInfinity (is almost always this)
AssemblyName = This is the name of the actual dll and can have .dll at the end
ClassName = This is the fully qualified class name
Text = My custom parameter that tells my custom handler what to put in the file

There is a more detailed blog on this here:

Happy coding!

Leave a Reply

Privacy Policy | Sitemap | © 2011 Blackbaud, Inc. All Rights Reserved

Digital Ocean