I created a PDF webapp where users are able to generate various type of PDF on both the computer and mobile phone. However, i run my program on a localhost and this is how i save my PDF based on my computer's file directory
var output = new FileStream(Path.Combine("C:\\Users\\apr13mpsip\\Downloads", filename), FileMode.Create);
However, when i publish my webapp onto azure, i wasn't able to download from both my computer and mobile phone. Therefore i believe that it could be due to my default file directory.
Hence i would like to ask how to do a default file directory for all computer and mobile phone?
Or could it be i left out something that is necessary when the webapp is published online
Thanks.
PS : I hardcoded a default file path in order for me to test my application on a localhost to ensure a perfect working condition. Therefore i'm finding a way to find a default common file directory for all mobile/computer users when they attempt to download the PDF instead of my usual hard-coded file path
UPDATE
I tried using the method Server.MapPath but receive some error.
var doc1 = new Document();
var filename = Server.MapPath("~/pdf") + "MyTestPDF" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".pdf";
// var output = new FileStream(Path.Combine("C:\\Users\\apr13mpsip\\Downloads", filename), FileMode.Create);
//iTextSharp.text.pdf.PdfWriter.GetInstance(doc1, output);
using (var output = File.Create(filename))
{
iTextSharp.text.pdf.PdfWriter.GetInstance(doc1, output);
}
doc1.Open();
This is the error i received
ObjectDisposedException was unhandled by user code
Cannot access a closed file.
When you write a Web Application you shall never use hard coded paths, and the last place where you should save files is C:\Users !! It does not matter whether this is Azure or not. It is general rule for any kind of web applications!
In your case I suggest that you create a folder within your application named pdf or something like that and save files there with the following code:
var fileName = Server.MapPath("~/pdf") + filename;
using (var output = File.Create(fileName) )
{
// do what you want with that stream
// usually generate the file and send to the end user
}
However there is even more efficient way. Use the Response.OutputStream and write the resulted PDF directly to the response. Will save you a lot of space on the local server, and the logic to delete unused generated files.
Related
I try to write some data with streamwriter in a .txt file and than to use those as cookies
var writer = new System.IO.StreamWriter(Application.StartupPath +
"\Cookies\cookies.txt");
But after I install application from .exe file and execute, it shows the error "Access is denied in path ..."
I am not sure if the problem is in path of file that I want to use as a file for cookies or in process of creating installation MSI/Setup of Application, even I include Cookies folder in application.
Do you have any suggestion which is the best practice to save "cookies" in win application?
Seems your source code is under some place where file writing is allowed, but when you running your exe then the location of the execution is not allowed for file write. Because you are writting your file in the exe execution path so file write permission is depend upon that execution location. If you execute exe from a location where file write alowed it won't throw exception and if a flace where file write is not allowed then it will throw exception. So my suggestion is use a allowed static place where user have file write permission, like AppData or Documents like below
var writer = new System.IO.StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\Cookies\cookies.txt");
or
var writer = new System.IO.StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\Cookies\cookies.txt");
Hope it will help
irst are you sure that the needed folder is under the proper folder structure? Because StartupPath will return the path to your exe file ?
We tried creating a txt file using this code
using (StreamWriter _testData = new StreamWriter(Server.MapPath("~/data.txt"), true))
{
_testData.WriteLine(" asd"); // Write the file.
}
But we get the message Access to the path 'L:...\data.txt' is denied
Can this be done with Anonymous disabled and NETWORK SERVICE out of the users group in security of the folder?
Upd: We have a web application and we want to track the number of clicks on a certain button to get statistics for a month of its usage by each user, we cant use any database (not even access).
Is the best approach to create a txt file?
Maybe have a look to the IIS trust level.
http://technet.microsoft.com/en-us/library/cc754779.aspx
Depending on your configuration (above and medium included), you will not be able to write a file outside the application directory.
Here's my solution for appending data to a textfile as a log.
using (var stream = System.IO.File.AppendText(Server.MapPath("~/App_Data/data.txt")))
{
stream.WriteLine("testing..");
stream.Flush();
}
Put that in your Index() method on your controller and it will append "testing.." for each visit. Enjoy :)
I use open XML to export excel file. SpreadsheetDocument.Create requires a file destination.
I want to get this file destination from user similar to a SaveFileDialog in Winforms.
How I get file destination from user? I use Asp.Net 4.0 and OpenXML SDK 2.5 .
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(destination, SpreadsheetDocumentType.Workbook);
For this functionality even if you use open/save dialog, it would show the client locations not the server locations. So here question is, do you want to save that file to the client machine or at the server machine?
If you want to save it to client machine then first save it on the server by any name and location you want and then initiate a download after that. It will automatically prompt download dialog in the client browser and there user would be able to select the location and filename (depending on the client browser settings).
If you want to save it only on server then just before generating the spreadsheet, prompt user for entering the filename (on the page from where the request is generated). If some of your folders are accessible to user then you can also prompt user to select one of the folders, otherwise choose one as per your choice/requirement. Use the filename and the location to generate the spreadsheet.
when a webserver is streaming a file down to the client, you don't have control of the destination folder. All you can do is:
specify the contents type (to aid client in determining how to handle)
specify filename
(I think) tell the client browser to save the file vs. displaying it automatically in the registered application (for example, PDFs usually display in the browser, but setting up the streaming correctly could force Save File dialog instead)
If you need to "cache" the file ion the web server, you export to a server folder that your server process has write permissions to. Then you stream to the client - the client will get the prompt from their browser and save where they want.
Look at Server.MapPath for example - it'll map virtual path to physical on your server. the question of permissions remains.
Depending on your particular case, you may be able to avoid saving to the server, if the export library has a way of returning a byte array or a stream, instead of saving to a file. In that case you just stream the return result to requester.
I am not familiar with the SDK you're using, but quick googling reveals this method of returning the document in a stream:
using (MemoryStream stream = new MemoryStream())
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook, true))
{
... work with the spreadsheetDocument, if needed
... prepare and stream to browser
}
}
Here's one of the references to your SDK I found
Use Environment.SpecialFolder enumerations. If you are looking for my documents then:
var destination = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(destination, SpreadsheetDocumentType.Workbook);
I am using ITextSharp for creating pdf in ASP.net, every thing works fine on my local machine, when I run it on IIS server, pdf is created successfully and can be open and view in the folder it is made, but I cannot open the pdf programmatically from C#.
I am using Process.Start(path) to open the file.
PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("TransferLetter/" + filenamee), FileMode.Create));
doc.Open();
DateTime date = DateTime.Now.Date;
html = html.Replace("[Date]", Request["Date"] + "");
html = html.Replace("[Address]", Request["MailingAddress"].ToString());
html = html.Replace("[PlotNo]", Request["PlotNumber"].ToString());
html = html.Replace("[Block]", Request["Block"].ToString());
html = html.Replace("[Size]", Request["PlotSize"].ToString());
string pa = Server.MapPath("TransferLetter/" + filenamee);
System.Diagnostics.Process.Start(pa);
This will never work this way. System.Diagnostics.Process.Start() runs on the server, not the client. When you're developing on your local machine you are both the server and the client so it appears to work but once you separate these two you get your failure.
To say that again but in a different way, you are asking the server to build your PDF and then you are instructing the server to launch its local copy of Adobe Reader and display the PDF to whoever is physically logged into the server at the moment. (Ok, not 100% true but pretty close.)
Instead you need to send the PDF to the client using something like Response.Redirect() or Response.Write(). Looking at your code you should be able to perform:
Response.Redirect("TransferLetter/" + filenamee)
Using iTextSharp you don't actually have to even write the PDF to disk. You could use a MemoryStream instead of a FileStream, call MemoryStream.ToArray() write before disposing of it and using Response.Write() on that byte array. If you are writing small PDFs and/or are planning on multiple people accessing this that might be the safer way.
you need to use ~ tilde operator to specify the current project folder path
Try This:
string pa = Server.MapPath("~/TransferLetter/" + filenamee);
I have an application MVC3 application. I want to log various things, like when a form particular form is submitted, to avoid having to write to a database, I want to log the details in an xml file.
The question is what folder should I use, some of the examples I have seen suggest the App_Data folder. What is the norm or recommended for the least issues?
So I use this:
// Create a new XmlSerializer instance with the type of the test class
var serializerObj = new XmlSerializer(typeof(CourseApplicationVM));
// Create a new file stream to write the serialized object to a file
var filename = string.Format("{0}-{1}-{2}{3}", "CourseApp",
viewModel.Course.Code + viewModel.Applicant.Name, DateTime.Now.Ticks, ".xml");
var filepath = Path.Combine(Server.MapPath("~/App_Data/Log"), filename);
TextWriter writeFileStream = new StreamWriter(filepath);
serializerObj.Serialize(writeFileStream, viewModel);
// Cleanup
writeFileStream.Close();
It works fine locally, but not when published to the server. Upon looking at the folder structure it is unsurprising, as it doesn't even have the App_Data folder when published. Which leads to this error:
Could not find a part of the path 'C:\inetpub\wwwroot\MyApplication\App_Data\Log\CourseApp-0385JoeBloggs-634734549879496695.xml'.
Exception Details: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\inetpub\wwwroot\MyApplication\App_Data\Log\CourseApp-0385JoeBloggs-634734549879496695.xml'.
Why is it that is hasn't got that folder (shouldn't it be published up)? And what is the normal location for the saving of such things?
Thanks,
David
Right Click on the folder and in context menu select "Include in to project/solution"
Make sure you rights on folder are set accordingly.