Quindi sto sviluppando un'applicazione che consente a un utente di compilare i documenti in formato digitale, quindi tali informazioni vengono acquisite dal server e un PDF viene popolato e restituito all'utente.
La logica interna per ogni pagina è piuttosto simile:
- Ricevi
Request
dal client - Apri il modello PDF appropriato dal file system
- Esegue un'iterazione sulle proprietà del% co_de ricevuto utilizzando la reflection
- Verifica se la proprietà contiene un attributo
Request
. - Se viene trovato l'attributo, compilare il campo PDF corrispondente dalla proprietà
PDFFieldName
.
- Verifica se la proprietà contiene un attributo
- Flatten PDF
- Restituisce PDF all'utente.
In questo flusso di controllo, assumiamo che ogni richiesta in entrata sia serializzata in una corretta classe di richieste pre-create. Le classi di richieste corrispondono ai post-dati provenienti dal client e, se necessario, contengono proprietà che calcolano i valori corretti per il PDF.
Le uniche parti del processo che variano in modo considerevole sono:
- Il percorso del file system per il file.
- Il tipo di classe che serializza i dati.
- Il nome file emesso.
A parte questo, ci sono pochissime differenze tra ogni processo (anche se ce ne possono essere alcuni). Quale modello di codice impedirebbe la maggior parte del riutilizzo del codice e sarebbe più adeguato per lo scenario indicato?
Modifica
Ecco un esempio di codice di ciò che sto facendo attualmente:
// PDF Generation Code
public byte[] GeneratePDF(string path, object response)
{
var pdfTemplate = path;
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)
{
pdfFormFields.SetField(attr.Name, property.GetValue(response)?.ToString() ?? "");
}
}
pdfStamper.FormFlattening = true;
pdfStamper.Close();
newPdf.Flush();
return newPdf.ToArray();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
finally
{
pdfStamper.Dispose();
pdfReader.Close();
pdfReader.Dispose();
newPdf.Close();
newPdf.Dispose();
}
return null;
}
Esempio di classe di risposta:
public class ShareInfoResponse
{
[PDFFieldName("Name1")]
public string name1 { get; set; }
[PDFFieldName("Name2")]
public string name2 { get; set; }
[PDFFieldName("Name3")]
public string name3 { get; set; }
[PDFFieldName("Name4")]
public string name4 { get; set; }
[PDFFieldName("Name5")]
public string name5 { get; set; }
[PDFFieldName("Name6")]
public string name6 { get; set; }
[PDFFieldName("Relationship1")]
public string relationship1 { get; set; }
[PDFFieldName("Relationship2")]
public string relationship2 { get; set; }
[PDFFieldName("Relationship3")]
public string relationship3 { get; set; }
[PDFFieldName("Relationship4")]
public string relationship4 { get; set; }
[PDFFieldName("Relationship5")]
public string relationship5 { get; set; }
[PDFFieldName("Relationship6")]
public string relationship6 { get; set; }
[PDFFieldName("SSN")]
public string ssn { get; set; }
}
Esempio di controller MVC:
public IActionResult ShareMedicalInfo(ShareInfoResponse response)
{
var path = _appEnvironment.ApplicationBasePath + @"\wwwroot\forms\";
const string file = "Authorization_to Share_Information.pdf";
return new FileContentResult(GeneratePDF(path + file, response), "application/pdf")
{
FileDownloadName = "Authorization_to Share_Information.pdf"
};
}