Recently, I needed an ActionResult implementation to return the Pdf documents from my Controller Action to MVC views and it tooks few minutes to build the functionality on the existing FileResult.
I decided to build a base class PdfResult to abstract the ContentType implementation as well as it will also serve as a common return type from the action method irrespective of derived implementation like Content, Path etc.
PdfResult Base class
///
/// PdfResult
/// Represents a base class that is used to send PDF file content to the response.
public abstract class PdfResult : FileResult
{
#region Constructor
///
/// Initializes a new instance of the FileResult class.
///
public PdfResult()
: base(System.Net.Mime.MediaTypeNames.Application.Pdf)
{
}
#endregion
}
PdfStreamResult It’s one of the implementation class for PdfResult to return the Pdf content as stream on HttpResponse Stream.
///
/// PdfStreamResult
/// Sends binary content to the response by using a Stream instance.
///
public class PdfStreamResult : PdfResult
{
// Fields
private const int _bufferSize = 0x1000;
#region Constructor
///
/// PdfContentResult
/// Initializes a new instance of the FileStreamResult class.
///
public PdfStreamResult(Stream fileStream)
: base()
{
if (fileStream == null)
{
throw new ArgumentNullException("fileStream");
}
this.FileStream = fileStream;
}
#endregion
#region Overriden Methods
///
/// WriteFile
/// Writes the file to the response. (Overrides FileResult.WriteFile(HttpResponseBase).)
protected override void WriteFile(HttpResponseBase response)
{
Stream outputStream = response.OutputStream;
using (this.FileStream)
{
byte[] buffer = new byte[0x1000];
while (true)
{
int count = this.FileStream.Read(buffer, 0, 0x1000);
if (count == 0)
{
return;
}
outputStream.Write(buffer, 0, count);
}
}
}
#endregion
///
/// FileContents
/// Gets the stream that will be sent to the response.
public Stream FileStream { get; private set; }
}
PdfPathResult
This implementation class return the Pdf document from a physical Pdf file on the server.
///
/// PdfPathResult
/// Sends the contents of a file to the response.
public class PdfPathResult : PdfResult
{
#region Constructor
///
/// PdfContentResult
/// Initializes a new instance of the FilePathResult class by using the specified file name and content type.
///
public PdfPathResult(string fileName)
: base()
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentException("Value cannot be null or empty.", "fileName");
}
this.FileName = fileName;
}
#endregion
#region Overriden Methods
///
/// WriteFile
/// Writes the file to the response. (Overrides FileResult.WriteFile(HttpResponseBase).)
protected override void WriteFile(HttpResponseBase response)
{
response.TransmitFile(this.FileName);
}
#endregion
///
/// FileContents
/// Gets the path of the file that is sent to the response.
public string FileName { get; private set; }
}
PdfContentResult
This implementation returns the Pdf document out of binary content of Pdf document.
///
/// PdfContentResult
/// Sends the contents of a binary file to the response.
///
public class PdfContentResult : PdfResult
{
#region Constructor
///
/// PdfContentResult
/// Initializes a new instance of the PdfContentResult class by using the specified file contents and content type.
///
public PdfContentResult(byte[] fileContents)
: base()
{
if (fileContents == null)
{
throw new ArgumentNullException("fileContents");
}
this.FileContents = fileContents;
}
#endregion
#region Overriden Methods
///
/// WriteFile
/// Writes the file content to the response. (Overrides FileResult.WriteFile(HttpResponseBase).)
protected override void WriteFile(HttpResponseBase response)
{
response.OutputStream.Write(this.FileContents, 0, this.FileContents.Length);
}
#endregion
///
/// FileContents
/// The binary content to send to the response.
public byte[] FileContents { get; private set; }
}
Controller Extensions
I needed to write these extension to have the calling code look similar to ViewResult or other result types.
///
/// Defines extensions for controllers
public static class ControllerExtensions
{
#region Pdf Extension method for Controller
///
/// Pdf
/// Creates a PdfContentResult object by using the file contents, content type, and the destination file name.
/// The Controller
/// The binary content to send to the response.
/// The file name to use in the file-download dialog box that is displayed in the browser.
/// The file-content result object.
public static PdfResult Pdf(this Controller controller, byte[] fileContents, string fileDownloadName)
{
return new PdfContentResult(fileContents) { FileDownloadName = fileDownloadName };
}
///
/// Pdf
/// Creates a PdfStreamResult object using the Stream object, the content type, and the target file name.
/// The Controller
/// The stream to send to the response.
/// The file name to use in the file-download dialog box that is displayed in the browser.
/// The file-stream result object.
public static PdfResult Pdf(this Controller controller, Stream fileStream, string fileDownloadName)
{
return new PdfStreamResult(fileStream) { FileDownloadName = fileDownloadName };
}
///
/// Pdf
/// Creates a PdfPathResult object by using the file name, the content type, and the file download name.
/// The Controller
/// The path of the file to send to the response.
/// The file name to use in the file-download dialog box that is displayed in the browser.
/// The file-stream result object.
public static PdfResult Pdf(this Controller controller, string fileName, string fileDownloadName)
{
return new PdfPathResult(fileName) { FileDownloadName = fileDownloadName };
}
#endregion
}
Example
PdfStreamResult
public PdfResult DownloadPdf()
{
Stream fileStream = ...; //initialization code to initialize the stream with Pdf File.
return this.Pdf(fileStream, "Sample.pdf");
}
PdfPathResult
public PdfResult DownloadPdf()
{
string filePath = ; //initialization code to initialize the string with Pdf File Path.
return this.Pdf(filePath, "Sample.pdf");
}
PdfContentResult
public PdfResult DownloadPdfContent()
{
string filePath = ; //initialization code to initialize the string with Pdf File Path.
byte[] pdfBytes = System.IO.File.ReadAllBytes(filePath);
return this.Pdf(pdfBytes, "sample.pdf");
return pdfContent;
}