c:\windows\system32\inetsrv\Test.pdf is denied - asp.net

I have a requirement to generate a pdf document on a button click on using visual web part- sharepoint 2010.
I am using the the open source library http://www.itextpdf.com/ for the same. I am able to execute the below code using the project type as a Windowns Application. But, when I want do it on a button click , I am receiving c:\windows\system32\inetsrv\Test.pdf' is denied. error.
Below is the code that I am using
public static void Main(string[] args) --Console Application
{
Console.WriteLine("PDF demo");
Document myDoc = new Document(PageSize.A4.Rotate());
try
{
PdfWriter.GetInstance(myDoc, new FileStream("Salman.pdf", FileMode.Create));
myDoc.Open();
myDoc.Add(new Paragraph("First pdf File made by Salman using Itext"));
}
catch (DocumentException ex)
{
Console.Error.WriteLine(ex.Message);
}
myDoc.Close();
}
}
But I want do the same on a button click event.
protected void pdfGenerator_OnClick(object sender, EventArgs e)
{
Document myDoc = new Document(PageSize.A4.Rotate());
try
{
PdfWriter.GetInstance(myDoc, new FileStream("Salman.pdf", FileMode.Create));---I get an error here
myDoc.Open();
myDoc.Add(new Paragraph("First pdf File made by Salman using Itext"));
}
catch (DocumentException ex)
{
Console.Error.WriteLine(ex.Message);
}
myDoc.Close();
}
}
Please help me , i dont understand the reason for the error. I am tyring it for the first time.

The problem is you are trying to create a PDF in a directory you do not have access to. This is because you are not specifying the directory to save the path; which causes it to default in the same location as the current working directory. In many cases, such as for ASP.NET; the default is the same as the location of the process. For ASP.NET, the process is w3wp.exe and resides in c:\windows\system32\inetsrv. Most identities that w3wp will run as (Network Service or AppPoolIdentity) do not have access to that directory. In fact, only system administrators do.
You need to save it somewhere else that the process has write permissions to here:
PdfWriter.GetInstance(myDoc, new FileStream("Janaki.pdf", FileMode.Create))
Should be something like:
PdfWriter.GetInstance(myDoc, new FileStream(#"C:\directoryIcanWriteTo\Janaki.pdf", FileMode.Create))
If you want to save it in the same place as the website, you would use HttpContext.Current.Server.MapPath:
PdfWriter.GetInstance(myDoc, new FileStream(HttpContext.Current.Server.MapPath("~/Janaki.pdf", FileMode.Create))
Regardless, the identity will still need write permissions to the directory if it doesn't have them. But you definitely shouldn't put them in inetsrv.

Just don't use "FileStream" which requires write permissions on the server. Replace it with MemoryStream and then flush its content on the user's browser.

Related

XML does not get saved in asp.net

I have a problem saving my xml-file.
i use this XMLwriter :
using (XmlWriter writer = XmlWriter.Create("CarsXML.xml"))
{
writer.WriteStartDocument();
writer.WriteStartElement("CarsXml");
foreach (Car item in cars)
{
writer.WriteStartElement("Car");
writer.WriteElementString("Brand", item.Brand);
writer.WriteElementString("Type", item.Type);
writer.WriteElementString("Price", item.Price);
writer.WriteElementString("Effect", item.Effect);
writer.WriteElementString("Year", item.year);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
}
Seems ok right? No compile errors..
I´ve also tried this just for testing :
XDocument doc = new XDocument(
new XElement("Root",
new XElement("Child", "content")
)
);
doc.Save("Root.xml");
Still no luck.. `ve trid this in a console app, and it works so the code must be fine..
I´ve also tried with a piece of code i found somewhere - using XmlDocument instead - but its the same deal.
What am i doing wrong?
When you are in a web application, the current directory is not the root directory of the web application. It's the directory where the IIS executable is, so that's somewhere in the Windows system directories.
Naturally you don't have write access to that directory from the web application, so you get some exception when you try to create a file there.
Specify the full path of the file that you want to create. You can use the MapPath method to get the physical path to a file from a virtual path. Example:
string fileName = Server.MapPath("/xmldata/CarsXML.xml");
using (XmlWriter writer = XmlWriter.Create(fileName))
...

providing feedback for file uploads

When uploading files to a server what information should be provided to the user for feedback? I have created a website that allows users to upload files to a server. I would think a progress bar would be nice or at the very least a message to let the users know that the process was successful or not. Another issue is how do I know that the operation was successful? Right now the only thing I can think of is to check if the files exist after they are saved. I am using C# .NET 2.0 on the server side. Here is an example of the code I have for saving the files...
private void fileUpload(HttpContext context)
{
string stgDir = #"myDir",
fullPath;
HttpFileCollection hfc = context.Request.Files;
for(int i = 0; i < hfc.Count; i++)
{
fullPath = Path.Combine(BASE_PATH, stgDir);
if(!Directory.Exists(fullPath))
{
Directory.CreateDirectory(fullPath);
}
if(hfc[i].ContentLength > 0)
{
fullPath = Path.Combine(fullPath,hfc[i].FileName);
hfc[i].SaveAs(fullPath);
}
}
}
If you don't get an exception is very unlikely that there was an error saving the file, so, add a try catch and show your user an error if exception is catch, or just a friendly message indicating the file was uploaded.
Regarding the info as feedback, that's up to you and what you would like the user to know, maybe success message and a link to the file would be enough.

How can save a text file in a folder created on an FTP server?

I have created an application which creates a folder on an FTP server when clicking on a button.
Now I need to store some text files to it.
How can I do this?
keep in mind you have to create a folder and set permission for read and write on the server then you can create a folder in which you can create any file type.
protected void Submit_ServerClick(object sender, EventArgs e)
{
`enter code here` using (StreamWriter _testData = new StreamWriter(Server.MapPath("~/data.txt"), true))
{
_testData.WriteLine("this is how you will create a file"); // Write the file.
}
}
or
File.WriteAllText(Server.MapPath("~/data.txt"), TextBox1.Text);

FileUpload control in asp.net throwing exception

I am trying to read an Excel sheet using C# which is to be loaded by end user from fileUpload control.
I am writing my code to save the file on server in event handler of another button control(Upload). But when I click on Upload Button I am getting this exception:
The process cannot access the file 'E:\MyProjectName\App_Data\sampledata.xlsx' because it is being used by another process.
Here is the code that I have used in event handler:
string fileName = Path.GetFileName(file_upload.PostedFile.FileName);
string fileExtension = Path.GetExtension(file_upload.PostedFile.FileName);
string fileLocation = Server.MapPath("~/App_Data/" + fileName);
//if (File.Exists(fileLocation))
// File.Delete(fileLocation);
file_upload.SaveAs(fileLocation);
Even deleting the file is not working, throwing the same exception.
Make sure, some other process is not accessing that file.
This error might occurs whenever you are trying to upload file, without explicitly removing it from memory.
So try this:
try
{
string fileName = Path.GetFileName(file_upload.PostedFile.FileName);
string fileExtension = Path.GetExtension(file_upload.PostedFile.FileName);
string fileLocation = Server.MapPath("~/App_Data/" + fileName);
//if (File.Exists(fileLocation))
// File.Delete(fileLocation);
file_upload.SaveAs(fileLocation);
}
catch (Exception ex)
{
throw ex.Message;
}
finally
{
file_upload.PostedFile.InputStream.Flush();
file_upload.PostedFile.InputStream.Close();
file_upload.FileContent.Dispose();
//Release File from Memory after uploading
}
The references are hanging in memory, If you are using Visual Studio try with Clean Solution and Rebuild again, if you are in IIS, just do a recycle of your application.
To avoid this problems try to dispose the files once you used them, something like:
using(var file= new FileInfo(path))
{
//use the file
//it will be automatically disposed after use
}
If i have understood the scenario properly.
For Upload control, I don't think you have to write code for Upload Button. When you click on your button,your upload control has locked the file and using it so it is already used by one process. Code written for button will be another process.
Prior to this, check whether your file is not opened anywhere and pending for edit.

Changing Databases in Crystal Reports for .NET

I have a problem which is perfectly described here (http://www.bokebb.com/dev/english/1972/posts/197270504.shtml):
Scenario:
Windows smart client app and the CrystalReportViewer for windows.
Using ServerFileReports to access reports through a centralized and disconnected folder location.
When accessing a report which was designed against DB_DEV and attempting to change its LogonInformation through the CrystalReportViewer to point against DB_UAT, it never seems to actually use the changed information.
It always goes against the DB_DEV info.
Any idea how to change the Database connection and logon information for a ServerFileReport ????
Heres code:
FROM A PRESENTER:
// event that fires when the views run report button is pressed
private void RunReport(object sender, EventArgs e)
{
this.view.LoadReport(Report, ConnectionInfo);
}
protected override object Report
{
get
{
ServerFileReport report = new ServerFileReport();
report.ObjectType = EnumServerFileType.REPORT;
report.ReportPath = #"\Report2.rpt";
report.WebServiceUrl = "http://localhost/CrystalReportsWebServices2005/ServerFileReportService.asmx";
return report;
}
}
private ConnectionInfo ConnectionInfo
{
get
{
ConnectionInfo info = new ConnectionInfo();
info.ServerName = servername;
info.DatabaseName = databasename;
info.UserID = userid;
info.Password = password;
return info;
}
}
ON THE VIEW WITH THE CRYSTAL REPORT VIEWER:
public void LoadReport(object report, ConnectionInfo connectionInfo)
{
viewer.ReportSource = report;
SetDBLogon(connectionInfo);
}
private void SetDBLogon(ConnectionInfo connectionInfo)
{
foreach (TableLogOnInfo logOnInfo in viewer.LogOnInfo)
{
logOnInfo.ConnectionInfo = connectionInfo;
}
}
Does anyone know how to solve the problem?
I know this isn't the programatic answer you're looking for, but:
One thing that helps with this sort of thing is not creating your reports connected to the database directly, but first you create a "Data Dictionary" for Crystal Reports (this is done in the Report Designer). Then you link all of your reports to this dictionary which maps the fields to the proper databases.
Done this way, you only have one place to change the database schema/connection info for all reports.
Also, in your report designer set the report to not cache the results (sorry I don't remember the exact option). Reports can either have their initial results included or not.
Don't you have to browse all the "databaseTable" objects of the report to redirect the corresponding connections? You'll find here my VB version of the 'database switch' problem ...
In your CrystalReportViewer object you should set
AutoDataBind="true"

Resources