Returning a Crystal report as a PDF ActionResult in ASP.Net MVC

Pieter van der Westhuizen, a professional freelance web & mobile developer and founder of Coalition Software.
Search for a command to run...

Pieter van der Westhuizen, a professional freelance web & mobile developer and founder of Coalition Software.
A recent requirement came up for configurable dynamic forms in a mobile application. There are a few dynamic form packages for Flutter, but I wanted a bit more control over the schema and behavior of the form. Here follows my attempt at creating dyna...

If you've ever written a mobile app with Flutter that integrates with an API, then you'll know that there are a lot of model objects that get passed between the app and the API. JSON Serialization in Flutter can also take a fair amount of boilerplate...

Back in May 2020, Microsoft announced a new feature for Azure Blob Storage called Blob Index. Essentially, this enables you to add key/value tags to your Blob objects and be able to query said Blob objects without having to use a separate service lik...

In my last post, "Using AWS Cognito with Xamarin Forms", I showed how to authenticate with Amazon Cognito using Xamarin Forms and the Xamarin.Essentials Web Authenticator. In this post, we'll go through the process of using the AWS Cognito Hosted UI ...

In this post, I'll show you how to quickly and easily set up user authentication for your Xamarin Forms app using Amazon Cognito. AWS Cognito is a user identity management solution by Amazon. It is a really easy way to add authentication to your appl...

In a recent project I needed to display a generated PDF contract document inside the browser. I found a great article by Patrick Kalkman illustrating how to create a custom ActionResult that converts a HTML string into a PDF using the iTextSharp library.
This seemed like the perfect solution, however, I later found that the conversion from HTML to PDF is not perfect at all and getting your design to look the same in PDF as it does in HTML is not easy. So I found another article by Hasibul Haque, where he shows how to return a Crystal Report as PDF using ASP.Net MVC.
The Crystal Report approach works well, as your design will look perfect. The only problem I had was Hasibul’s approach returned the PDF as a download and I wanted to display it inside the browser. I combined Patrick and Hasibul’s approaches and what I came up with was a CrystalReportPdfResult
The CrystalReportPdfResult is an ASP.Net ActionResult, that return the Crystal Report as a PDF file. The result (using an iframe) looks like this inside the browser:

To generate the result as indicated by the previous image, follow these steps:
The entire code listing for the CrystalReportPdfResult class follows:
CrystalReportPdfResult.cs
public class CrystalReportPdfResult : ActionResult
{
private readonly byte[] _contentBytes;
public CrystalReportPdfResult(string reportPath, object dataSet)
{
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load(reportPath);
reportDocument.SetDataSource(dataSet);
_contentBytes = StreamToBytes(reportDocument.ExportToStream(ExportFormatType.PortableDocFormat));
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.ApplicationInstance.Response;
response.Clear();
response.Buffer = false;
response.ClearContent();
response.ClearHeaders();
response.Cache.SetCacheability(HttpCacheability.Public);
response.ContentType = "application/pdf";
using (var stream = new MemoryStream(_contentBytes))
{
stream.WriteTo(response.OutputStream);
stream.Flush();
}
}
private static byte[] StreamToBytes(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
Next, we need to create the Crystal Report that will be returned as a PDF. Do this by following these steps:

Next, we need to create the actual Action on a Controller that will return the CrystalReportPdfResult, by following these steps:
public CrystalReportPdfResult Pdf()
{
List<Customer> model = new List<Customer>();
model.Add(new Customer { CompanyName = "Blah Inc.", ContactName = "Joe Blogs" });
string reportPath = Path.Combine(Server.MapPath("~/Reports"), "rptCustomers.rpt");
return new CrystalReportPdfResult(reportPath, model);
}
We’ll embed the PDF using an , so open a view. In this case we’ll use About.cshtml and replace it’s mark-up with the following:
About.cshtml
@{
ViewBag.Title = "Customer Report";
}
<h2>@ViewBag.Title.</h2>
<p>This is the customer report</p>
<div class="row">
<div class="col-md-10">
<iframe src="@Url.Action("Pdf", "Home")" height="500" width="100%"></iframe>
</div>
<div class="col-md-2">
<h3>Other page content</h3>
<button type="button" class="btn btn-primary">Click here</button>
</div>
</div>
Note, that we’re using the @Url.Action helper to set the src attribute of the
In case you’re wondering how to send the Crystal Report as a PDF attachment on an email, here is the code:
Code Snippet
public void SendReport()
{
List<Customer> model = new List<Customer>();
model.Add(new Customer { CompanyName = "Blah Inc.", ContactName = "Joe Blogs" });
ReportDocument reportDocument = new ReportDocument();
reportDocument.Load(Path.Combine(Server.MapPath("~/Reports"), "rptCustomers.rpt"));
reportDocument.SetDataSource(model);
using (var stream = reportDocument.ExportToStream(ExportFormatType.PortableDocFormat))
{
SmtpClient smtp = new SmtpClient
{
Port = 587,
UseDefaultCredentials = true,
Host = "smtp.gmail.com",
EnableSsl = true
};
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("you@gmail.com", "gmailPassword");
var message = new System.Net.Mail.MailMessage("you@gmail.com", "recipient@gmail.com", "subject", "body");
message.Attachments.Add(new Attachment(stream, "report.pdf"));
smtp.Send(message);
}
}
I’ve tested this on the latest version of Chrome, Firefox and Internet Explorer and it works on all of them.
Hope this helps someone that needs something similar. Thank you for reading. Until next time, keep coding!
Download the sample project here.
If you have any comments or questions, please feel free to ask leave a comment or drop me a line on Twitter.