Posted on Feb 26, 2010

How to return a SQL Report as a PDF/Excel/CSV file from an ASP.Net MVC controller

SQL Reports is a wonderful tool for creating and publishing enterprise reports, yet it’s Web Forms viewer has it’s drawbacks such as requiring an Active-X control for printing and it’s not available in ASP.Net MVC.

A good solution to utilizing SQL Reports in an ASP.Net MVC application is to use the SQL Reports Web Services API to render the report as a PDF, Excel, or CSV file and to have your action method return the rendered report as a Filestream to the browser.

The source code for this project is available on a Subversion server here:  http://code.yanachik.org/public/MVCSQLReportDemo/

The steps involved are:

  1. Create a Web Reference to the SQL Reports Report Execution Web Service.
  2. Create an Action Method that returns a FileStreamResult.
  3. Create a proxy to the Web Service and set the credentials.
  4. Render the report.
  5. Return the report as a file stream.

Create a Web Reference to the SQL Reports Report Execution Web Service

In your ASP.Net MVC project add a Web-Reference to the Report Execution Web Reference to the following URL:  http://REPORTSERVER/ReportServer/ReportExecution2005.asmx and name it rsExecService.  Even if you’re using SQL Reports 2008, the Web Reference is still set for 2005.

To do this, right-click on the project in Visual Studio and select Add Web Reference…  The “Add Web Reference” dialog will appear.  Fill in the URL to your SQL Reports Report Execution Web Service and hit enter or click on the Go button.  Once the Web Service is found you fill out the Web Reference Name with rsExecService and click the Add Reference button.

AddingWebReference

Create an Action Method that returns a FileStreamResult

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public FileStreamResult PrintReport(string id)
{

}

The System.Web.Mvc.OutputCache attribute tells your browser to not cache the report.  If you have static data you can remove this attribute.

Create a proxy to the Web Service and set the credentials

// Create a new proxy to the web service
rsExecService.ReportExecutionService rsExec = new rsExecService.ReportExecutionService();

// Authenticate to the Web service using Windows credentials
rsExec.Credentials = new System.Net.NetworkCredential("USERNAME", "Password", "DOMAIN");

Render the report

When loading the report, the file name is the full path for the report.  In this case “Test Report” is at the root of the Report Server.  If it was in a folder then the path would be “/Folder 1/Folder 2/Report Name”.

// Load the selected report.
rsExec.LoadReport("/Test Report", null);

// Prepare Render arguments
string encoding = String.Empty;
string mimeType = String.Empty;
string extension = String.Empty;
rsExecService.Warning[] warnings = null;
string[] streamIDs = null;

// Prepare report parameters.
rsExecService.ParameterValue[] parameters = new rsExecService.ParameterValue[1];
parameters[0] = new rsExecService.ParameterValue();
parameters[0].Value = id;
parameters[0].Name = "id";

// Set the parameters for the report needed.
rsExec.SetExecutionParameters(parameters, "en-us");

//Render the report to a byte[]
Byte[] byteInfo = rsExec.Render("PDF", null, out extension, out encoding, out mimeType, out warnings, out streamIDs);

Return the report as a file stream.

System.IO.MemoryStream ms = new System.IO.MemoryStream();
ms.Write(byteInfo, 0, byteInfo.Length);
ms.Position = 0;

HttpContext.Response.AddHeader("content-disposition", "attachment; filename=FILENAME.pdf");

return new FileStreamResult(ms, "application/pdf");

The final Action Method looks like this:

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public FileStreamResult PrintReport(string id)
{
    // Create a new proxy to the web service
    rsExecService.ReportExecutionService rsExec = new rsExecService.ReportExecutionService();

    // Authenticate to the Web service using Windows credentials
    rsExec.Credentials = new System.Net.NetworkCredential("USERNAME", "Password", "DOMAIN");

    // Load the selected report.
    rsExec.LoadReport("/Test Report", null);

    // Prepare Render arguments
    string encoding = String.Empty;
    string mimeType = String.Empty;
    string extension = String.Empty;
    rsExecService.Warning[] warnings = null;
    string[] streamIDs = null;

    // Prepare report parameters.
    rsExecService.ParameterValue[] parameters = new rsExecService.ParameterValue[1];
    parameters[0] = new rsExecService.ParameterValue();
    parameters[0].Value = id;
    parameters[0].Name = "id";

    // Set the parameters for the report needed.
    rsExec.SetExecutionParameters(parameters, "en-us");

    //Render the report to a byte[]
    Byte[] byteInfo = rsExec.Render("PDF", null, out extension, out encoding, out mimeType, out warnings, out streamIDs);

    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    ms.Write(byteInfo, 0, byteInfo.Length);
    ms.Position = 0;

    HttpContext.Response.AddHeader("content-disposition", "attachment; filename=FILENAME.pdf");

    return new FileStreamResult(ms, "application/pdf");
}

Posted on Nov 10, 2008

Linq To SQL Entity Data Context InsertOnSubmit vs Attach

After writing Unit tests lately I’ve been trying to test my business logic (which is all done in the Entity Manager) without actually submitting data to the database.  I’ll create my Items and Customers and do an InsertOnSubmit to get them into the Entity Manager context, but never call SubmitChanges().

This gets the data into the database, however, it does not get the objects into the EntityManager’s data context.  If I were to create a Customer Order and then create a Customer Order Item I can then Add the Customer Order Item to the Customer Order and the order item is then available within the Customer Order context, but the Customer Order is still not available within the Entity Manager context.  To do that, you need to Attach the Customer Order to the CustomerOrders table.

Posted on Oct 31, 2008

Visual Studio 2008 Service Pack 1 Javascript Formatting Drives Me Nuts

With all of the goodies included with Service Pack 1 for Visual Studio 2008, the one thing that Microsoft did not do right is Javascript formatting.  First of all, it’s really slow.  Second of all, it doesn’t seem to be consistent with it’s indenting.

For me, I’d like to do my own formatting.  So, to turn off the Javascript formatting in Visual Studio 2008 go to Tools – Options – Text Editor – JScript – Formatting.  And uncheck all of the checkboxes in the Automatic Formatting group.

Posted on Oct 10, 2008

Yahoo DataTable editorSaveEvent Change from YUI 2.5.2 to 2.6.0

In Yahoo YUI 2.5.2 the Yahoo DataTable editorSave Event’sData Cell Editor has changed.  To get to the data record for the editor it is no-longer oArgs.editor.record, but rather oArgs.editor.getRecord();

DataTable.subscribe("editorSaveEvent", EditorChanged);

function EditorChanged(oArgs)
{
    var record = oArgs.editor.getRecord();
}

Posted on Aug 19, 2008

How to preconfigure your Ruby on Rails application for MySQL

Rails 2.0.2 now defaults your app’s database to SQLite3 (I believe because OSX comes pre-shipped with it).  In order to generate a rails application and having it setup to MySQL is pretty easy.

In your when you create your app add (-d mysql) in the rails command:  rails -d mysql myapp

Posted on Mar 4, 2008

A series of Short reviews…

There were a series of announcements and reviews that came out lately, here’s a sample:

Google MobileGoogle Gears has gone mobile – what a great idea.  When your mobile device can’t get a signal (such as on an airplane) but you need to do some work, you can now access your mobile apps though google gears.  Zoho runs on Google Gears, hopefully Zoho Planner is supported.  Unfortunately, Google Gears only runs on IE Mobile.
Yahoo onePlace OverviewYahoo has announced onePlace which is a mobile service designed to take your Yahoo settings and make them available on your mobile device.  Your stock portfolio is available, your favorites, your Flickr account, your My Yahoo feeds – everything is available.  Look for this to come out shortly.
Google Docs Vs Microsoft Workspaces Read Write Web has a good feature comparison between Google Docs and Microsoft Office Workspaces.  Google has everything between email, documents, calendars, etc.  For the life of me I can’t figure out why they don’t have a task tracking system.  Is it too easy?  Too basic for them?  It would be a hot commodity.

Posted on Mar 2, 2008

Windows Presentation Foundation Flotzam has a new UI

Flotzam, a life streaming screensaver based all on Microsoft’s new Windows Presentation Foundation (WPF) put out a contest for redesigned UI.  Here’s a screencast of the winner.


Flotzam Design Contest Winner

Posted on Mar 2, 2008

Posted on Mar 2, 2008

Is SocialThing.com the big hit out of SXSW?

ReadWriteWeb is trying to predict what app will be the big hit at SXSW, and they seem to have concluded that whatever it is, it will involve social networking.  RWW seem impressed with SocialThing, and predict that if they get their iPhone interface working by SXSW then thy’ve got a real chance at being a huge hit this year.  The idea behind the app is to allow you and your friends to keep tabs on what one-another is doing via different services available for life streaming.  From their website:

Get your digital life in order

socialthing! is a digital life manager that puts what you do online into one place. See everything that’s going on with your friends in all the sites you use, post stuff to multiple places at once and more!

Here are some photos from their flickr account:

Socialthing! Adds Pownce

 

And their iPhone interface:

Socialthing! Mobile - Home

Socialthing! iPhone Edition

Socialthing! Mobile - Post Status

Posted on Feb 28, 2008

Check out my Pownce Feed

I’ve place a badge on my home page that displays my two latest Pownce posts, and dedicated an entire page Pownce Feeds that lists my 30 most recent Pownce posts.  Things that ramble off my brain that don’t deserve a full blog post will get Pownced.