patterncsharpMinor
Implementing a PDF generator that converts classes into PDFs
Viewed 0 times
pdfsconvertsintogeneratorthatclassesimplementingpdf
Problem
I'm building a tool that takes in web requests and deserializes JSON requests into a C# class. Each page calls a different controller URL that is looking for a specific request. Once the request is received, I pipe the request into a method that iterates over each property in the class using reflection looking for the presence of a certain attribute. If the attribute is present, it reads the PDF field name from that attribute and the application then uses ITextSharp to populate a PDF form.
My solution received many pats on the back from my coworkers, but I still feel like it can be done better, in a much more decoupled way. My initial idea was to create an interface that each class implements, and then use custom methods inside each class to map out the properties manually. However, this seems a bit more cumbersome and involved.
Does anyone have any input on what a better practice might be?
PDF generation method:
```
public static byte[] GeneratePDF(string basepath, string filepath, object response)
{
var pdfTemplate = filepath;
var pdfReader = new PdfReader(pdfTemplate);
var newPdf = new MemoryStream();
var pdfStamper = new PdfStamper(pdfReader, newPdf);
try
{
var pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("Date", DateTime.Now.ToString("MM/dd/yyyy"));
var properties = response.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
var attr = (PDFFieldName)Attribute.GetCustomAttribute(property, typeof(PDFFieldName));
if (attr != null)
{
var prop = property.GetValue(response)?.ToString() ?? "";
if (prop.ToLower() == "true") prop = "On";
pdfFormFields.SetField(attr.Name, prop);
}
}
pdfStamper.Close();
newPdf.Flush();
var finalPdf = newPdf.ToArray();
var signature = response.GetType().GetProperty("signature");
if (sign
My solution received many pats on the back from my coworkers, but I still feel like it can be done better, in a much more decoupled way. My initial idea was to create an interface that each class implements, and then use custom methods inside each class to map out the properties manually. However, this seems a bit more cumbersome and involved.
Does anyone have any input on what a better practice might be?
PDF generation method:
```
public static byte[] GeneratePDF(string basepath, string filepath, object response)
{
var pdfTemplate = filepath;
var pdfReader = new PdfReader(pdfTemplate);
var newPdf = new MemoryStream();
var pdfStamper = new PdfStamper(pdfReader, newPdf);
try
{
var pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("Date", DateTime.Now.ToString("MM/dd/yyyy"));
var properties = response.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
var attr = (PDFFieldName)Attribute.GetCustomAttribute(property, typeof(PDFFieldName));
if (attr != null)
{
var prop = property.GetValue(response)?.ToString() ?? "";
if (prop.ToLower() == "true") prop = "On";
pdfFormFields.SetField(attr.Name, prop);
}
}
pdfStamper.Close();
newPdf.Flush();
var finalPdf = newPdf.ToArray();
var signature = response.GetType().GetProperty("signature");
if (sign
Solution
You can consider not to call GC.SuppressFinalize by trying to use the "using" statement instead.
You can consider to use "var" only for anonymous expressions. This way it improves readability.
Example it is good to use "var" for some LINQ operations or anonymous expressions. It is not appropriate to use to define string like below
using (MemoryStream ms = new MemoryStream()) {
using (PdfStamper stamper = new PdfStamper(reader, ms, '\0', true)) {
// do stuff
}
return ms.ToArray();
}You can consider to use "var" only for anonymous expressions. This way it improves readability.
Example it is good to use "var" for some LINQ operations or anonymous expressions. It is not appropriate to use to define string like below
var test = "teststring";Code Snippets
using (MemoryStream ms = new MemoryStream()) {
using (PdfStamper stamper = new PdfStamper(reader, ms, '\0', true)) {
// do stuff
}
return ms.ToArray();
}var test = "teststring";Context
StackExchange Code Review Q#150458, answer score: 3
Revisions (0)
No revisions yet.