Embedding text file in asp.net project - asp.net

I added text file to my web project. Right click and clicking on properties
menu I choose ,Build Action -> Resource.
How can I retrieve the content of the file in my code behind page.
I try this but I received stream null
internal string GetFromResources(string resourceName)
{
Assembly assem = this.GetType().Assembly;
using (Stream stream = assem.GetManifestResourceStream(resourceName))
{
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
But it's not working.
Please help

Try changing the Build Action to Embedded Resource and make sure that the resource name contains the namespace. i.e.
MyProjectNamespace.MyTextFileName.txt
If your file is in a sub folder then use:
MyProjectNamespace.SubFolderName.MyTextFileName.txt

I solved it, below are the steps that I took.
First of all I defined text file as embedded resource.
Second problem was that I did not added assembly name space to the text file.
So I changed the function and added namespace
internal string GetFromResources(string resourceName)
{
Assembly assem = this.GetType().Assembly;
**List<string> listNameSpaces = assem.GetTypes().Select(t => t.Namespace).Distinct().ToList<string>();**
foreach (string ns in listNameSpaces)
{
**string nsResourceName = ns + "." + resourceName;**
using (Stream stream = assem.GetManifestResourceStream(nsResourceName))
{
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
}
return string.Empty;
}

Related

Switch from Visual Studio 2012 --> 2019 Broke async Task and FileResult

An ASP.NET MVC solution that was working fine in VS 2012 stopped working in 2019 and I cannot find what has changed to break it.
Originally I had the code in the first block - the async task would go to the file storage and retrieve the file, and then the file was sent to the browser using a FileResult that the controller called automatically. After a VERY painful change to VS 2019 and updating everything (.NET runtime, 3rd party libraries, etc.) I have the application working again except for this issue.
I tried creating a new FileStreamResult (which is in the 2nd block) but that does not get called either. When I click on a link that calls this:
<a href="/Cert/File?folder=&filename=#HttpUtility.UrlEncode(FilePath)" ...
It gives me a blank page instead of downloading the file as it used to.
public async Task FileAsync(string folder, string filename)
{
AsyncManager.OutstandingOperations.Increment();
var ReadObjectTask = _fileStorageProvider.ReadObjectDataAsync(folder, filename);
Stream ROResult = await ReadObjectTask;
AsyncManager.Parameters["stream"] = ROResult;
AsyncManager.Parameters["filename"] = filename;
AsyncManager.OutstandingOperations.Decrement();
}
public FileResult FileCompleted(Stream stream, string filename)
{
if (stream == null)
{
return File(Server.MapPath(Url.Content("~/Content/bad_file.png")), "image/png");
}
var file = new FileStreamResult(stream, MIMEAssistant.GetMIMEType(filename));
if (filename.Contains("/"))
{
filename = filename.Split('/').Last();
}
file.FileDownloadName = filename;
return file;
}
Here is the FileStreamResult I tried:
public System.Web.Mvc.FileStreamResult FileCompleted(Stream stream, string contentType, string filename)
{
if (stream == null)
{
string bFile = Server.MapPath(Url.Content("~/Content/bad_file.png"));
Stream blankfile = System.IO.File.OpenRead(bFile);
return File(blankfile, MIMEAssistant.GetMIMEType(bFile), System.IO.Path.GetFileName(bFile));
}
if (filename.Contains("/"))
{
filename = filename.Split('/').Last();
}
return File(stream, MIMEAssistant.GetMIMEType(filename), filename);
}
(The filename.Contains part is old code from a predecessor that I just need to replace with Path.GetFileName - sorry I did not clean it up before I posted.)
I decided to make the Async Task one of type and moved the
stream processing into that procedure to solve my problem. I do not know
why the Async Task that was working in 2012 stopped in 2019.
public async Task<FileResult> FileAsync(string folder, string filename)
{
AsyncManager.OutstandingOperations.Increment();
var ReadObjectTask = _fileStorageProvider.ReadObjectDataAsync(folder, filename);
Stream ROResult = await ReadObjectTask;
AsyncManager.Parameters["stream"] = ROResult;
AsyncManager.Parameters["filename"] = filename;
AsyncManager.OutstandingOperations.Decrement();
if (ROResult == null)
{
return File(Server.MapPath(Url.Content("~/Content/bad_file.png")), "image/png");
}
var file = new FileStreamResult(ROResult, MIMEAssistant.GetMIMEType(filename));
file.FileDownloadName = System.IO.Path.GetFileName(filename);
return file;
}

Displaying mht file in iframe

I need to display mht file stored in zip archive in frame on the page
<iframe src="#Url.Action("LoadInstrucion","Pharmacy", new {id= Model.Instrukciya })"></iframe>
Action in MVC Controller returning file
public ActionResult LoadInstrucion(string id)
{
var bytes = InstructionsLoader.LoadInstrucion(id);
return File(bytes, "multipart/related");
}
Action for getting byte array from file
public static byte[] LoadInstrucion(string zipFileName)
{
string zipfilePath = $#"{HttpContext.Current.Request.PhysicalApplicationPath}Content\inst\{zipFileName}.zip";
if (File.Exists(zipfilePath))
{
using (var zipStream = new FileStream(zipfilePath, FileMode.Open))
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
{
if (archive.Entries.Count > 0)
{
var file = archive.Entries[0];
var stream = file.Open();
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
}
}
return new byte[0];
}
If I navigate to Url I see the requested mht file, but it is not displayed in iframe. In Dev console I get warning:
Attempted to load a multipart archive into an subframe

Asp.net check if HttpPostedFileBase is a Word Document

I need a function which checks if the HttpPostedFileBase is a word document. I don't want to check against file extension because that can be changed by the user.
I tried to read the Header information of the binary data, which starts with PK (for example, PDF files starts with %PDF), but i don't know if i can rely upon that.
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
string header = null;
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
char[] buffer = new char[5];
sr.Read(buffer, 0, 4);
header =
string.Format("{0}{1}{2}{3}{4}", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
}
}
if (header.StartsWith("%PDF"))
{
// PDF Document
}
if (header.StartsWith("PK"))
{
// Microsoft Word Document ?
}
return Json(new { }, JsonRequestBehavior.AllowGet);
}
The first two letters of a word document (DOCX) are PK because a DOCX file is actually a PKZip file; so no, this is not reliable.
The ForensicsWiki page here may help:
http://www.forensicswiki.org/wiki/Word_Document_%28DOC%29
and
http://www.forensicswiki.org/wiki/DOCX

Generating PDFs using Phantom JS on .NET applications

I have been looking into phantomJS and looks like it could be a great tool to use generating PDFs. I wonder if anyone have successfully used it for their .NET applications.
My specific question is: how would you use modules like rasterize.js on the server, receive requests and send back generated pdfs as a response.
My general question is: is there any best practice for using phantomJS with .NET Applications. What would be the best way to achieve it?
I am fairly new in .NET World and I would appreciate the more detailed answers. Thanks everyone. :)
I don't know about best practices, but, I'm using phantomJS with no problems with the following code.
public ActionResult DownloadStatement(int id)
{
string serverPath = HttpContext.Server.MapPath("~/Phantomjs/");
string filename = DateTime.Now.ToString("ddMMyyyy_hhmmss") + ".pdf";
new Thread(new ParameterizedThreadStart(x =>
{
ExecuteCommand("cd " + serverPath + #" & phantomjs rasterize.js http://localhost:8080/filetopdf/" + id.ToString() + " " + filename + #" ""A4""");
})).Start();
var filePath = Path.Combine(HttpContext.Server.MapPath("~/Phantomjs/"), filename);
var stream = new MemoryStream();
byte[] bytes = DoWhile(filePath);
return File(bytes, "application/pdf", filename);
}
private void ExecuteCommand(string Command)
{
try
{
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
}
catch { }
}
public ViewResult FileToPDF(int id)
{
var viewModel = file.Get(id);
return View(viewModel);
}
private byte[] DoWhile(string filePath)
{
byte[] bytes = new byte[0];
bool fail = true;
while (fail)
{
try
{
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
}
fail = false;
}
catch
{
Thread.Sleep(1000);
}
}
System.IO.File.Delete(filePath);
return bytes;
}
Here is the action flow:
The user clicks on a link to DownloadStatement Action. Inside there, a new Thread is created to call the ExecuteCommand method.
The ExecuteCommand method is responsible to call phantomJS. The string passed as an argument do the following.
Go to the location where the phantomJS app is and, after that, call rasterize.js with an URL, the filename to be created and a print format. (More about rasterize here).
In my case, what I really want to print is the content delivered by the action filetoupload. It's a simple action that returns a simple view. PhantomJS will call the URL passed as parameter and do all the magic.
While phantomJS is still creating the file, (I guess) I can not return the request made by the client. And that is why I used the DoWhile method. It will hold the request until the file is created by phantomJS and loaded by the app to the request.
If you're open to using NReco.PhantomJS, which provides a .NET wrapper for PhantomJS, you can do this very succinctly.
public async Task<ActionResult> DownloadPdf() {
var phantomJS = new PhantomJS();
try {
var temp = Path.Combine(Path.GetTempPath(),
Path.ChangeExtension(Path.GetRandomFileName(), "pdf")); //must end in .pdf
try {
await phantomJS.RunAsync(HttpContext.Server.MapPath("~/Scripts/rasterize.js"),
new[] { "https://www.google.com", temp });
return File(System.IO.File.ReadAllBytes(temp), "application/pdf");
}
finally {
System.IO.File.Delete(temp);
}
}
finally {
phantomJS.Abort();
}
}
Here's some very basic code to generate a PDF using Phantom.JS but you can find more information here: https://buttercms.com/blog/generating-pdfs-with-node
var webPage = require('webpage');
var page = webPage.create();
page.viewportSize = { width: 1920, height: 1080 };
page.open("http://www.google.com", function start(status) {
page.render('google_home.pdf, {format: 'pdf', quality: '100'});
phantom.exit();
});

How to convert array of byte to original file (to provide download of file)

I m using Opendialogbox to read the file. Then stored the file in byte[] array.
file --> byte []
byte[] --> stored on SQL AZure in varbinary(max) field.
Here is my code:
OpenFileDialog ofd = new OpenFileDialog();
if ((bool)ofd.ShowDialog())
{
FileStream fileStream = ofd.File.OpenRead());
byte[] buffer = new byte[fileStream.Length];
int read = 0;
using (BinaryReader binaryReader = new BinaryReader(fileStream))
{
do
{
read = binaryReader.Read(buffer, 0, Convert.ToInt32(fileStream.Length));
// Stored the File in byte[] Array buffer
} while (read > 0);
}
}
Now I want to convert this byte array to the original file (like .doc,.txt,jpeg). i know the extension in which file is to be convert.
SQL AZure ---> byte[] // done
byte[] ---> to original file. // Problem
Please give solution to download the file.
One way - not necessarily the best - is as follows:
using (MemoryStream ms = new MemoryStream(theBytes))
{
using (FileStream fs = new FileStream(string.Format("C:\\tempfile.{0}", theExtension)))
{
ms.WriteTo(fs);
}
}
namespace FileSaveDialogDemo
{
public partial class MainPage : UserControl
{
#region Fields
SaveFileDialog dialog= new SaveFileDialog();
#endregion
#region Constructors
public MainPage()
{
InitializeComponent();
this.dialog = new SaveFileDialog();
try
{
this.dialog.DefaultExt = ".txt";
this.dialog.Filter = "Text Files|*.txt|Log Files|*.log|All Files|*.*";
this.dialog.FilterIndex = 2;
}
catch ( Exception ex )
{
this.tblError.Text = "Error configuring SaveFileDialog: " + ex.Message;
}
}
#endregion
private void btnSaveFile_Click( object sender, RoutedEventArgs e )
{
bool? dialogResult = this.dialog.ShowDialog();
if ( dialogResult == true )
{
try
{
byte[] fileBytes; // your varbinary file from database
using (Stream fs = (Stream)dialog.OpenFile())
{
fs.Write(fileBytes, 0, fileBytes.Length);
fs.Close();
lblMsg.Content = "File successfully saved!";
}
}
catch ( Exception ex )
{
this.tblError.Text = "Error calling service: " + ex.Message;
}
}
} // End of Function
}// End of MainPage class
}
It seems the issue you have has probably nothing to do with saving a binary file; it is more likely a basic security issue. Try saving to a path on which you have programmatic write access. For example, try saving to your My Documents directory instead of C:. Try using the Environment.SpecialFolder enumeration like this, and append the file name + extension.
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
You have a number of other ways to work around this issue, including starting Visual Studio in Elevated Mode (run as Administrator), and/or allow "Everyone" write access to your C:\ drive. But I wouldn't recommend these techniques necessarily; consider saving to a folder where the security settings are lower than c:\, such as My Documents.

Resources