Error happens during file open in asp.net on wep page? - asp.net

I try to open the file and update content in the file, it gets sum error like this.
My code
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If Request.QueryString("log") = "no" Then
pinfo.Text = "Invalid Username / Password"
End If
Session.Clear()
Dim FileWriter As StreamWriter
Dim FileReader As StreamReader
Dim Countstr As String
FileReader = File.OpenText("/dmkg/Counter.txt")
Countstr = FileReader.ReadLine
FileReader.Close()
Countstr = Countstr + 700
FileWriter = File.CreateText("/dmkg/Counter.txt")
FileWriter.WriteLine(Countstr)
FileWriter.Close()
End Sub
Check the code and tell me where I am going wrong.

You have to Pass Correct PATH in OpenText Method not File Name
File.OpenText()
Eg:
Dim path As String = "c:\temp\MyTest.txt"
FileReader = File.OpenText(path)
So Make sure your file path is correct.
If it's stored in server then you need to use Server.Mappath()
FileReader = File.OpenText(Server.MapPath("/dmkg/Counter.txt"))
Server.MapPath
To Enable a Access
To grant ASP.NET write access to a path,
right-click the file in Explorer,
choose "Properties" and select the Security tab.
Click "Add" to add the appropriate user or group (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6).
Highlight the needed account, and check the boxes for the desired
access.

Related

Azure Asp.net download files from DropBox using Dropbox.Api

My asp.net web app requires downloading files from DropBox.
In DropBox, I created an app and have the API key and Auth Token, Secret, etc.
In my web app I have reference to Dropbox.Api and can create DropboxClient.
Like so:
Dim myDBClient As New DropboxClient("my_token_auth")
What do I do next? Does anyone have sample code.
I read I need to call async method to download such as code below.
But the code is not working. Not failing either but does nothing.
Any help would be appreciated. Thank you
Dim folder As String = "C:\Data"
Dim file2 As String = "myFile.txt"
Using response = myDBClient.Files.DownloadAsync("/" & folder & "/" & file2)
Using fileStream = File.Create("C:\Data\myFile.txt")
(response.GetContentAsStreamAsync()).CopyTo(fileStream))
End Using
End Using
You need to use Await to get the expected result.
Demo code:
Dim myDbClient As New DropboxClient("auth token")
Dim folder = "test" 'dropbox folder name
Dim fileName = "1.txt" 'dropbox file name
Dim response As IDownloadResponse(Of FileMetadata) = Await myDbClient.Files.DownloadAsync("/" + folder + "/" + fileName)
Dim bytes = Await response.GetContentAsByteArrayAsync()
Using fileStream = Create("D:\tom\2.txt") ' local path
fileStream.Write(bytes, 0, bytes.Length)
End Using
Update:
Add the detail test steps:
1.Create dropbox app and generate the auth token.
2.Create the folder and upload the file to dropbox folder
3.Create an Asp.net empty project and add a webform.aspx file named DropBoxApiTest.aspx and set it as start page.
4.To install Dropbox.Api, run the following command in the Package Manager Console:
PM> Install-Package Dropbox.Api
5.Add the download button in the Webpage
<asp:Button ID="_btnDownload" runat="server" Text="Download" />
6.Add the click event for the button and the following code.
Protected Async Sub _btnDownload_Click(sender As Object, e As EventArgs) Handles _btnDownload.Click
Dim token = "xaMln4bUnRAAAAAAAAAAIq...."
Dim myDbClient As New DropboxClient(token)
Dim folder = "test" 'dropbox folder name
Dim fileName = "1.txt" 'dropbox file name
Dim response As IDownloadResponse(Of FileMetadata) = Await myDbClient.Files.DownloadAsync("/" + folder + "/" + fileName)
Dim bytes = Await response.GetContentAsByteArrayAsync()
Using fileStream = Create("D:\tom\download.txt") ' local path
fileStream.Write(bytes, 0, bytes.Length)
End Using
End Sub
7.We also need to change aspx Async to true
8.Test it locally.

Saving Files to user Computer in VB.Net

I have look for days, with no luck.
Can anyone tell me how to save files in VB.Net to any computer? There are lost of articles, but those only tell you about saving to your own computer by giving folder access, not a random user's computer.
You can see my example here http://hanontest.com/POShellCreator.aspx (You have to enter text into task code, project id and notes field, then click create. Then click export, you will see the error.)
I can go to a local Pizza shop website and download a menu pdf, I know its possible.
In my example it saves when you click the button, I would like a save as dialog if anyone knows how to do that as well.
Here is the save string:
Dim regDate As Date = Date.Now()
Dim strDate As String = regDate.ToString(".yyyy\.MM\.dd")
TextBox5.Text = "c:\temp\" & Vendor & "&" & Vendor2 & "&" & Vendor3 & "&" & Vendor4 & TaskEmpty & strDate & ".csv"
Here is how I am saving:
Public Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'Define Path to save file.
Dim path As String = TextBox5.Text
' Create or overwrite the file.
Dim fs As FileStream = File.Create(path)
' Add text to the file.
Dim info As Byte() = New UTF8Encoding(True).GetBytes(TextBox3.Text)
fs.Write(info, 0, info.Length)
fs.Close()
End Sub
The error you're seeing there is because you're attempting to save the text file to the server's
file system, which you don't have write access to.
To return a file to user from the server you need to do a little more work, and it's not going to simple on a postback from a button.
You need to send the data down to the client in the Response.OutputStream, instead of your page, and also tell the browser to treat it as a file download:
Response.ContentType = "text/plain";
Response.AppendHeader("Content-Disposition", "attachment; filename=textFile.csv");

How to create file on server with special privileges on Asp .net using visual basic?

One of the client requirements is that the server generate files and store them on a special folder. This files created can not be modified by users or deleted.
So the only way I thought is to generate this files with elevated privileges so a normal user can't delete or modify them.
But the question is how can I generate a file with this privileges that normal users can interact with this files... only download from server.
I use this code to generate the file... But I don't know how to configure it for elevated privileges.
This is the button which generate the file and allow to download it:
Protected Sub ibtGenerar_OnClick(ByVal sender As Object, ByVal e As ImageClickEventArgs)
oArchivoTelecredito.NombreArchivo = txtNombreArchivo.Text
oArchivoTelecredito.SesionDetalleArchivosTelecredito = New List(Of DetalleArchivoTelecreditoBE)
Dim oArchivoTelecreditoSL As New ArchivoTelecreditoSL
Response.AddHeader("Content-disposition", "attachment;filename=" & oArchivoTelecredito.NombreArchivo & ".txt")
Response.ContentType = "application/octet-stream"
Response.BinaryWrite(oArchivoTelecreditoSL.GeneraArchivoTelecredito(oArchivoTelecredito, Server.MapPath(oArchivoTelecredito.NombreArchivo)))
Response.End()
End Sub
This is the function which create the file on server:
Public Function GeneraArchivoTelecredito(ByVal telecredito As ArchivoTelecreditoBE, ByVal ruta As String) As Byte()
Dim lineas As Integer = telecredito.SesionDetalleArchivosTelecredito.Count + 1
Dim registro(0 To lineas) As String
registro(0) = Me.ObtenerCabeceraArchivoTelecredito(telecredito)
Dim archivo = ruta & ".txt"
Using escritor As New StreamWriter(archivo)
For index = 0 To lineas
escritor.WriteLine(registro(index))
Next
escritor.Close()
End Using
Dim lector As FileStream
lector = File.Open(archivo, FileMode.Open)
Dim bytes(lector.Length) As Byte
lector.Read(bytes, 0, lector.Length)
lector.Close()
Return bytes
End Function
If you want to set the file to be read-only then you can use
File.SetAttributes("PathToFile", FileAttributes.ReadOnly).
You could also set the permissions on the directory itself instead of the individual files - see this post: https://serverfault.com/questions/3878/is-there-a-way-to-prevent-a-file-from-being-deleted

FileUpload within a Wizard Control, Processed at the End

This is related to my previous question. An unforeseen issue arose with the Wizard control.
I now know how to upload to FTP, however when using the FileUpload control inside a Wizard control, when you move to the next step, the File you selected gets cleared because of the postback. I need to be able to rename the file according to the results from the Wizard before uploading. So...
I finish my wizard
It uploads some stuff to a database
Renames the file according to those results
Uploads the renamed file to the FTP server
I suspect I will need to follow a procedure something like this, having an upload button next to FileUpload
On "Upload" button click stream the file to the Web Server.
Complete the Wizard.
If the wizard completes successfully, rename file and stream to FTP server.
If the wizard fails, what? Delete the file from the web server? How?
I think I understand the process, so I would like help on how to split my FTP Upload function into two parts with the proper error handling for when the wizard fails.
It would be a great help if you please use the following code as a base. Thanks as always :)
Protected Sub UploadFile(ByVal NewFilename As String)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
'Function one? - Problem, "NewFilename" depends on the output of the Wizard,
' but obviously it has not been called yet.
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + NewFilename), FtpWebRequest)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
Dim myFileStream As Stream = FileUpload1.FileContent
myFtpWebRequest.ContentLength = myFileStream.Length
'Function two?
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
myFileStream.CopyTo(requestStream)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
End Sub
-- ANSWER ---
Here's my final implementation based on input from Icarus :)
For brevity I have excluded the error catching.
'This function is what kicks things off...
Protected Sub UploadFileToWebServer() Handles btnUploadFile.Click
Dim TempDir As String = "C:\TEMP", FileName As String = "uploadedfile.tmp", FilePath As String
If Not Directory.Exists(TempDir) Then
Directory.CreateDirectory(TempDir).Attributes = FileAttributes.Directory
End If
FilePath = TempDir + "\" + FileName
Session.Add("FileName", File1.FileName) 'Keep track of uploaded file name
File1.SaveAs(FilePath)
Session.Add("File", FilePath)
End Sub
After the file is uploaded to the web server, we can continue through the wizard, and when the "Finish" button is clicked, the wizard data gets submitted to the database. The filename is based on the inserted record ID. The following function gets called by the "Final" button click after the record is inserted, and the file finally gets uploaded to the FTP server with the filename changed accordingly.
Protected Sub UploadFileToFtpServer(ByVal FileLinkStr As String)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
'Defines the filename, path, and upload method, and connection credentials
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + FileLinkStr), FtpWebRequest)
'Be sure to authenticate prior to uploading or nothing will upload and no error
myFtpWebRequest.Credentials = New NetworkCredential(ftpUsername, ftpPassword)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
'Streams the file to the FTP server
'Retrieves File temporarily uploaded to the Web Server during Wizard Processing
Dim iStream As New FileInfo(Session.Item("File"))
Dim myFileStream As Stream = iStream.OpenRead
myFtpWebRequest.ContentLength = myFileStream.Length
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
myFileStream.CopyTo(requestStream)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
End Sub
Your understanding is correct. Once you upload the file to the web server (you'd need to place it in a temp directory somewhere and keep track of the file name you gave it) and the wizard completes successfully, you grab that file, rename it accordingly and upload it to the ftp server. If fails, simply call:
File.Delete(Path_to_file_uploaded_on_temp_directory);
You can keep track of the file name given originally, by storing it in Session, for example. When you upload the file to the server initially, do something like Session["FileName"]=Path_to_temp_directory+fileName;
On the final step of the Wizard, get the file name from Session and either rename it and upload it to the FTP Server or delete it.
Of course you need to account for possible name conflicts, etc. You can use a Guid to generate a random name for the file, for example.
I hope I explained this clearly.
EDIT
To make sure I understand correctly...
You need your user to go through all the steps of a Wizard kind of thing
During the process, you ask your user to upload a file.
Because the user has to select a file before the last step of the wizard, you are forced to upload the file immediately the user clicks on the "Next" button to go to the next step of the wizard.
At the very last step of the Wizard, you need to determine whether the file the user has selected should be uploaded to an ftp server (presumably, another box different from your web server) or should be discarded completely.
If the file needs to be uploaded to the FTP server, it needs to be renamed with a special name.
Based on the above, my suggestion is:
When the user clicks "Next" on the step where he selects the file from his computer, you need to save the file immediately to a temporary location on your web server. You save the file to this temporary folder on your web server by doing something like:
if(FileUpload1.HasFile) //user selected a file
{
try
{
//D:\temp is a temp directory on the Web Server
FileUpload1.PostedFile.SaveAs(#"D:\temp\"+FileUpload1.FileName);
//Store the FULL PATH TO the file just uploaded on Session
Session["FileName"]="D:\temp\"+FileUpload1.FileName;
}
catch (Exception ex)
{
//Handle it.
}
}
On the last step of the wizard, assuming everything was successful, do this
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
' You know the NewFileName because it's the output of the wizard
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + NewFilename), FtpWebRequest)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
'Here you need to read the Original File
Dim myFileStream As Stream = new FileStream(Session["FileName"]),FileMode.Open,FileAccess.Read,FileShare.ReadWrite)
myFtpWebRequest.ContentLength = myFileStream.Length
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
myFileStream.CopyTo(requestStream)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
If you decide that you should delete the original file uploaded by the user because he did not complete the wizard successfully, you can simply do:
try
{
File.Delete (Session["FileName"]);
}
catch(Exception ex)
{
//Handle it.
}

Zero size files uploaded with FTP FileUpload

I've been reading gobs of articles on FTP upload in ASP.NET recently and they all seem to make sense, but every time I've tried implementing them I either get an empty file uploaded, or no file at all. Here are some of the articles I've been reading:
Managing FTP Transfers from an ASP.NET Web Page By John Peterson
FileUpload Control Doesn’t Give Full Path….HELP!!!!
How to: Upload Files with the FileUpload Web Server Control
They're all great articles, but like I said, having issues :(
I know exactly what the problem is but I don't know how to fix it. I can pass the file name from the FileUpload control, but the path does not exist for security concerns. However, the StreamReader object requires the fully qualified path of the file to be uploaded, so how the heck do I get that? I'm at my wits end! >.<
Let's use the example by John Peterson that I linked above. Here's the code:
Protected Sub btnUploadFile_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
Dim myStreamWriter As StreamWriter
myFtpWebRequest = WebRequest.Create("ftp://ftp_server_name/filename.ext")
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
myStreamWriter = New StreamWriter(myFtpWebRequest.GetRequestStream())
'IT BREAKS HERE BECAUSE THE CLIENT PATH IS WRONG!!
myStreamWriter.Write(New StreamReader(Server.MapPath("filename.ext")).ReadToEnd)
myStreamWriter.Close()
myFtpWebResponse = myFtpWebRequest.GetResponse()
myFtpWebResponse.Close()
End Sub
See? No data in the uploaded file :(
Now my latest implementation looks like this, but the uploaded file is much larger than the source, and corrupted. Seriously, what the heck am I doing wrong? I've been two LONG days at this, grrr...
Protected Sub btnUploadFile2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
filename = Path.GetFileName(FileUpload1.FileName)
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + filename), FtpWebRequest)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
'NEW APPROACH USING THE STREAM OF THE FILE FROM THE FileUpload Control
'CORRECT BYTE LENGTH - in sourceStream.BaseStream
Dim sourceStream As New StreamReader(FileUpload1.FileContent)
'WRONG BYTE LENGTH - in sourceStream.ReadToEnd()
Dim fileContents As Byte() = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd())
sourceStream.Close()
myFtpWebRequest.ContentLength = fileContents.Length
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
requestStream.Write(fileContents, 0, fileContents.Length)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
End Sub
Thanks ever so much to Adam Maras for the amazing answer. I'll leave my blunders here for others to benefit who find this thread ;)
First of all, you must upload through the web server if you're going to use ASP.NET like this. Without installing a plugin on the client's browser or using an ActiveX control (or similar) you absolutely cannot upload directly from the client machine to the FTP server.
I assume you're uploading binary files; if that's the case, the way you're using StreamReaders and StreamWriters could be corrupting the binary contents of the file. Instead, we can use the Stream.CopyTo method to move the data verbatim from one stream to the other.
I've modified your method to use this pattern instead:
Protected Sub btnUploadFile2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
filename = Path.GetFileName(FileUpload1.FileName)
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + filename), FtpWebRequest)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
Dim myFileStream As Stream = FileUpload1.FileContent
myFtpWebRequest.ContentLength = myFileStream.Length
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
myFileStream.CopyTo(requestStream)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
End Sub
The FileUpload.SaveAs() method saves to the Web server's local file system, and can't write to a URI or FTP site. To do that, you'll need to create a WebRequest.
See the MSDN reference for the FileUpload control here: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload.saveas.aspx
and for the FTP use of a WebRequest here: http://msdn.microsoft.com/en-us/library/ms229715.aspx
Note the example given in the FileUpload documentation saves to c:\temp\uploadedfiles. I'd suggest you use Path.GetTempFileName() instead as this is guaranteed to give you a file that can always be written no matter what environment you're under.
The data gets corrupted because you are reading the file as if it was text, but it's not.
Use a BinaryReader instead of a StreamReader so that you can read the data as bytes directly:
Dim fileContents As Byte()
Using sourceStream As New BinaryReader(FileUpload1.FileContent)
fileContents = sourceStream.ReadBytes(Int32.MaxValue)
End Using

Resources