Tuesday, November 03, 2009

Downloading a PDF from Stream using XAF

At times you need to deliver PDF content or any content for that matter and the option to save the streams to a file and download are not always ideal. If your an XAF user and need to accomplish such a task here is how to do it. As we know downloading from a Stream is handled using an IHttpHandler along with an ashx file used to direct the user for downloading. To get started, first create an IHttpHandler. Set the IsReusable to false.

public bool IsReusable
get { return false; }

In the ProcessRequest do the following:

public void ProcessRequest(HttpContext context)
context.Response.ContentType = "application/pdf";
DevExpress.Xpo.IDataLayer dataLayer = XpoDefault.GetDataLayer(WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, DevExpress.Xpo.DB.AutoCreateOption.SchemaAlreadyExists);
using (DevExpress.Xpo.Session session = new DevExpress.Xpo.Session(dataLayer, null))
DataObject myDatasource = session.FindObject(new BinaryOperator("Oid", new Guid(context.Request.Params["oid"])));
context.Response.AddHeader("Content-Disposition", "attachment; filename=MyPDFName.pdf");
context.Response.BinaryWrite(myDatasource.PDFBlogField); // byte[]

Now that you have your handler done, lets get the ASHX file using it.

Create a Text File in your Project.Web project and rename it to PDFStream.ashx (Or whatever you want to name it), then add the following: (Replace Class with your NameSpace and class name)
Note: I usually create a Custom folder to keep track of these pages since they are not part of XAF themselves

<%@ WebHandler Language="C#" Class="Project.Web.Module.Handlers.MyPDFHandler" %>

This points your ashx file to the handler which will take care of passing the stream to your user.

When you have that ready, the next step is to create the Controller that will call this file.

In your Project.Web.Module project, add a controller. Set the TargetObjectType in the constructor to your class type which this will be used for. Add a SimpleAction to your controller and set the TargetObjectType for the action. Subscribe to the Execute event and add the following:

private void btnShowPDF_Execute(object sender, SimpleActionExecuteEventArgs e)
if (View.CurrentObject != null)
WebApplication.Redirect(String.Format("~/Custom/PDFStream.ashx?oid={0}", ((DataObject)View.CurrentObject).Oid));

And thats it, your action will direct the user to the ashx page which will return a file attachment to the user. Don't worry, the user will not be directed away from the current page, and the best part is you dont have to write files to the disk on your server.

Creative Commons License
Blogged Information and Code is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.