SharpShooter report from an ASP.NET MVC application

Andrew Kazyrevich
 
Last time I talked about sharing reports as files – but let me rekindle your interest with one more option.
 
We can share content on a web page.
 
No wonder, obviously – but there seem to be rather important implementation details behind the scenes, so the approach definitely deserves its own article. So let’s move on and see how to implement SharpShooter reports within an ASP.NET MVC app!

Step 1 of 2. Preparing the report.

Our task for today will be an ASP.NET MVC application which would display a report listing all the blogs.perpetuumsoft.com bloggers (as if the widget on the right hand side of the website was not enough of an eyesore :) ):
 

 
To this end, we create a database and a table:

CREATE DATABASE MyTest
USE MyTest

CREATE TABLE Bloggers (
	Id         BIGINT IDENTITY(1,1) NOT NULL,
	Name       NVARCHAR(100) NOT NULL,
	PostsCount INT NOT NULL,
	CONSTRAINT PK_Id PRIMARY KEY (Id)
)

…and insert the data (notice the “SQL Server 2008″-like syntax: if you’re working with an earlier version you’d need to use the less fancy plain inserts):

INSERT INTO Bloggers (Name, PostsCount) 
VALUES
    ('Andrew Kazyrevich', 15),
    ('Darina Merzlikina', 1),
    ('Dmitry Zhukov', 1),
    ('Eugene Akinshin', 2),
    ('Marketing Dept', 83),
    ('Mikhail Payson', 1),
    ('Sergey Kraynov', 2),
    ('Sergey Piskov', 5),
    ('Vitaliy Korney', 6)

Now we need to generate a SharpShooter report off that data – and why not use the limitless power of powershell helpers:
 

 
The above command would generate a scaffolded report for us, displaying the names and post counts of the bloggers. The operation takes a few seconds on my laptop and brings up Report Designer (where we can finally do some highly creative job like realigning the textboxes and changing fonts) – and voilà, the report is totally ready. The following Powershell command:

  Show-Report C:\Powershooter\3eb7f80918b1.rst

will bring it up in all its glory:
 

 

Step 2 of 2. Displaying report in ASP.NET MVC

So, our task is to display the above report on a web page, and hence achieve the ultimate objective of report sharing (we can for sure allow the users to download it as a .pdf file or print it out).
 
And here’s the code from the bird’s-eye view:

    public class HomeController : Controller
    {
        ...
        public ActionResult Report()
        {
            return new PdfReportResult("report.rst");
        }
    }

The above PdfReportResult is just a normal ContentResult which would return you some .pdf content – and “report.rst” is the report definition file which we renamed from the autogenerated 3eb7f80918b1.rst and saved into App_Data.
 
Here’s how its ExecuteResult method looks like:

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.Clear();

        string appDataPath = context.HttpContext.Server.MapPath("~/App_Data");
        string reportFile = Path.Combine(appDataPath, _reportDefinitionFile);
        response.RenderReport(reportFile);

        if (SaveAs != null) {
            response.AddHeader("content-disposition", "attachment;filename=" + SaveAs);
        }
        response.Charset = "";
        response.Cache.SetCacheability(HttpCacheability.NoCache);
        response.ContentType = "application/pdf";
        response.End();
    }

You probably noticed the magic RenderReport guy – that’s an extension method on HttpResponseBase, just to keep the code clean:

    internal static void RenderReport(this HttpResponseBase response, string reportFile)
    {
        var template = (Document)XSerializationManager.Read(reportFile);
        var engine = new RenderEngine(null, new ReportManager()) { 
                Objects = new ObjectPointerCollection() 
        };
        var report = engine.RenderDocument(template);

        var pdf = new PdfExportFilter();
        pdf.Export(report, response.OutputStream);
    }

The above code is probably the most difficult part. It deserializes the template from the original .rst file and creates a render engine which would generate the final report – which in turn gets written into the output stream as a pdf.
 
Once we get that right, we’re done. Here’s the final result you would see from the web application:
 

Summary.

Sharing a report is possible not only by exporting it as a file, but also by making it accessible from a web application.
 
In this post we’ve seen how to do that for an ASP.NET MVC app. If you’d like to take a peek at source code of this example – feel free to browse it on BitBucket or grab a .zip archive. Give it a try and let me know how it works for you.
 
Happy reporting! :)
 

September 3rd, 2011

Comments

  1. Cool post. But I think it’s not very actual since yesterday :)

    We have just released new product. It’s native HTML and JS report viewer and server side adopted for ASP.NET (through WCF) and ASP.NET MVC.

    So, export to PDF is a past ;) . Future is SharpShooter Reports.Web :)

    New product’s sample is here
    http://www.perpetuumsoft.com/Demo/SSReports.Web/Web/StartPage.htm

  2. Andrew Kazyrevich:

    Doh! I flicked through the link – great news Mikhail, that’s something I wanted to implement myself but didn’t have time! :)

  3. Yeap. It’s hard to find about a thousand of man hours to do this ;)

Leave a Comment