Encrypting file conent and decrypt it while reading C# - c#

I am using entity framework(WebAPI/C#/VS2019) and using below code to save file and display file.
Save Code
Document document = new Document();
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(attachment_data); //attachment_data is string
document.document_content=plainTextBytes;//document_content is byte[]
db.Documents.Add(document);
db.SaveChanges();
Below code is used to show saved file
[Route("api/documents/download")]
[HttpGet]
public HttpResponseMessage Download(int documentid)
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var document = db.Documents.Where(e => e.id.Equals(documentid)).FirstOrDefault();
if (document != null)
{
var stream = new System.IO.MemoryStream(document.document_content);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = document.name
};
}
return result;
}
Both Save file and downloading file is working fine.
The issue is how to encrypt the file content before Saving to Database?I saw few SO links but most of the methods are taking string as input and string as output.Not sure which one will fit in this scenario.

Related

How to convert XML to Byte to File/PDF

I have successfully done "find and replace" which created an xml. Now I want to convert the newly created xml file to pdf which will be attached as a file and sent in a mail.
The result of the Base64String was tested on a base64 pdf file converter but the pdf cannot be opened. Got this error: Something went wrong couldn't open the file
HOW CAN I MAKE THIS WORK?
public async Task<string> CreateDocument(string PolicyNumber)
{
var policy = await _context.Policy.SingleOrDefaultAsync(p => p.PolicyNumber == PolicyNumber);
ArgumentNullException.ThrowIfNull(policy, "Policy Not Available");
//CreatePolicyDocument
//create policy document
var files = #"C:\Users\PATHTODOCUMENT\holderTest.docx";
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(files, true))
{
string docText;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("XCONCLUSION_DATEX");
var newWordText = regexText.Replace(docText, "Hi Everyone!");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(newWordText);
Encoding encoding = Encoding.UTF8;
byte[] docAsBytes = encoding.GetBytes(newWordText);
File.WriteAllBytes("hello.pdf", docAsBytes);
var file = Convert.ToBase64String(docAsBytes);
}
}
//send message
//
return "";
}
PDF file has its own construct,so you can't generate a pdf file with the contentstring of xml file dirctly.
If you really want to convert xml contentstring to PDF,you could try iTextSharp.
I tried with a simple demo,and here's the code:
[HttpPost]
public IActionResult XMLtoPDF([FromForm] Try T1)
{
var streamContent = new StreamContent(T1.file.OpenReadStream());
var filestring = streamContent.ReadAsStringAsync().Result;
MemoryStream outputStream = new MemoryStream();
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, outputStream);
//PDF settings
PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
doc.Open();
var paragraph = new Paragraph(filestring);
doc.Add(paragraph);
doc.Close();
outputStream.Close();
var pdfArray = outputStream.ToArray();
return File(pdfArray, "application/pdf");
}
Result:

angular 4 download pdf comes out blank

Hello I am trying to download a pdf from a report that i create on the server. When I create it I save it on the server for a moment then I make a second call and download it.
The following is the code that is on the web API:
var rootDirectory = HostingEnvironment.MapPath("~");
var filePath = $#"{rootDirectory}\Temp\{file}.pdf";
var bytes = File.ReadAllBytes(filePath);
File.Delete(filePath);
var memoryStream = new MemoryStream(bytes);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(memoryStream.ToArray())
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "report.pdf"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
then I get back to the typescript and here is the code that I use do download it:
this.reportsService
.download(id)
.subscribe(r => {
let pdf =r._body;
var pdfName = `${this.selectedReport.name}.pdf`;
let blob = new Blob([pdf], { type: 'application/pdf' });
window.open(URL.createObjectURL(blob));
});
});
I should mention that when I open the pdf from where it is saved on the server it is correct.
Can someone please tell me what I'm missing?

How to send a zip file from Web API 2 HttpGet

I'm trying to figure it out how to create new zip file from a given folder path, and sending it back to the sender.
The need is that the file will be downloaded at the sender that requested it.
I've seen alot of answers but none helped me with the exact answer.
My code:
Guid folderGuid = Guid.NewGuid();
string folderToZip = ConfigurationManager.AppSettings["folderToZip"] + folderGuid.ToString();
Directory.CreateDirectory(folderToZip);
string directoryPath = ConfigurationManager.AppSettings["DirectoryPath"];
string combinedPath = Path.Combine(directoryPath, id);
DirectoryInfo di = new DirectoryInfo(combinedPath);
if (di.Exists)
{
//provide the path and name for the zip file to create
string zipFile = folderToZip + "\" + folderGuid + ".zip";
//call the ZipFile.CreateFromDirectory() method
ZipFile.CreateFromDirectory(combinedPath, zipFile, CompressionLevel.Fastest, true);
var result = new HttpResponseMessage(HttpStatusCode.OK);
using (ZipArchive zip = ZipFile.Open(zipFile, ZipArchiveMode.Read))
{
zip.CreateEntryFromFile(folderFiles, "file.zip");
}
var stream = new FileStream(zipFile, FileMode.Open);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "file.zip"
};
log.Debug("END ExportFiles()");
return ResponseMessage(result);
In your controller:
using System.IO.Compression.FileSystem; // Reference System.IO.Compression.FileSystem.dll
[HttpGet]
[Route("api/myzipfile"]
public dynamic DownloadZip([FromUri]string dirPath)
{
if(!System.IO.Directory.Exists(dirPath))
return this.NotFound();
var tempFile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid()); // might want to clean this up if there are a lot of downloads
ZipFile.CreateFromDirectory(dirPath, tempFile);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(new FileStream(tempFile, FileMode.Open, FileAccess.Read));
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
return response;
}
UPD: Workaround the File Already Exists

Angular/Web API 2 returns invalid or corrupt file with StreamContent or ByteArrayContent

I'm trying to return a file in a ASP.NET Web API Controller. This file is a dynamically-generated PDF saved in a MemoryStream.
The client (browser) receives the file successfully, but when I open the file, I see that all the pages are totally blank.
The thing is that if I take the same MemoryStream and write it to a file, this disk file is displayed correctly, so I assume that the problem is related to the file transfer via Web.
My controller looks like this:
[HttpGet][Route("export/pdf")]
public HttpResponseMessage ExportAsPdf()
{
MemoryStream memStream = new MemoryStream();
PdfExporter.Instance.Generate(memStream);
memStream.Position = 0;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(memStream.ToArray()); //OR: new StreamContent(memStream);
return result;
}
Just to try, if I write the stream to disk, it's displayed correctly:
[HttpGet][Route("export/pdf")]
public HttpResponseMessage ExportAsPdf()
{
MemoryStream memStream = new MemoryStream();
PdfExporter.Instance.Generate(memStream);
memStream.Position = 0;
using (var fs = new FileStream("C:\\Temp\\test.pdf", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
memStream.CopyTo(fs);
}
return null;
}
The differences are:
PDF saved on disk: 34KB
PDF transferred via web: 60KB (!)
If I compare both files contents, the main differences are:
File Differences
On the left is the PDF transferred via web; on the right, the PDF saved to disk.
Is there something wrong with my code?
Maybe something related to encodings?
Thanks!
Well, it turned out to be a client (browser) problem, not a server problem. I'm using AngularJS in the frontend, so when the respose was received, Angular automatically converted it to a Javascript string. In that conversion, the binary contents of the file were somehow altered...
Basically it was solved by telling Angular not to convert the response to a string:
$http.get(url, { responseType: 'arraybuffer' })
.then(function(response) {
var dataBlob = new Blob([response.data], { type: 'application/pdf'});
FileSaver.saveAs(dataBlob, 'myFile.pdf');
});
And then saving the response as a file, helped by the Angular File Saver service.
I guess you should set ContentDisposition and ContentType like this:
[HttpGet][Route("export/pdf")]
public HttpResponseMessage ExportAsPdf()
{
MemoryStream memStream = new MemoryStream();
PdfExporter.Instance.Generate(memStream);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(memStream.ToArray())
};
//this line
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "YourName.pdf"
};
//and this line
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return result;
}
Try this
[HttpGet][Route("export/pdf")]
public HttpResponseMessage ExportAsPdf()
{
MemoryStream memStream = new MemoryStream();
PdfExporter.Instance.Generate(memStream);
//get buffer
var buffer = memStream.GetBuffer();
//content length for header
var contentLength = buffer.Length;
var statuscode = HttpStatusCode.OK;
var response = Request.CreateResponse(statuscode);
response.Content = new StreamContent(new MemoryStream(buffer));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentLength = contentLength;
ContentDispositionHeaderValue contentDisposition = null;
if (ContentDispositionHeaderValue.TryParse("inline; filename=my_filename.pdf", out contentDisposition)) {
response.Content.Headers.ContentDisposition = contentDisposition;
}
return response;
}

How can I convert IEnumerable<CustomType> to Byte64 for file download

I'm using WebApiContrib.Formatting.xlsx to create and download a Microsoft Excel file. My problem is that when called from the client the file can't be opened and several method were tried. When dealing with PDF the problem was resolved converting the output to Byte64 like this:
var response = new HttpResponseMessage
{
Content = new StringContent(Convert.ToBase64String(output.ToArray()))
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Report.pdf"
};
return response;
In the case of WebApiContrib.Formatting.xlsx I have an IEnumerable. How can convert it the same way as the PDF.
var subscriptionExcelModels = subscriptionPlansConverted as SubscriptionExcelModel[] ?? subscriptionPlansConverted.ToArray();
This is my snippet of the last part of the code for the excel file:
var ret = Request.CreateResponse(HttpStatusCode.OK,subscriptionExcelModels);
ret.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
ret.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Report.xlsx"
};
return ret;

Categories