search folder through directory ASP VB.NET - asp.net

Is there a way to search folder name(whether its root folder or subfolder and with files inside) through web vb.net? I searched all over the internet and haven't found single help. this is what i've done so far. but this is in windows forms.
I am looking for web forms. thank you
Protected Sub search_Click(sender As Object, e As EventArgs) Handles Search.Click
Dim MainFldr = "d:\shared\"
Dim SKfiles() As System.IO.FileInfo
Dim FldrInfo As New System.IO.DirectoryInfo(MainFldr)
Dim flpth As String
flpth = ""
ListBox2.Items.Clear()
SKfiles = FldrInfo.GetFiles("*" & txtfolder.Text & "*.*", IO.SearchOption.AllDirectories)
For Each MySearchfile In SKfiles
flpth = ""
flpth = MySearchfile.DirectoryName + "\" + MySearchfile.Name
ListBox2.Items.Add(flpth)
Application.DoEvents()
Next
End Sub

Well, it turns out you can do the same in web land.
However, one huge "issue" to remember?
For any web page url, web page link, web page document reference? You will use the web site URL for that file in question.
So, say you have the web site (root) and then a folder called Images.
images\cat.jpg
So, the path name for the WEB SITE MARK up will be:
"~/images/cat.jpg
however, WHEN you run code behind? (your vb.net code). Now, ALL AND EVERY file reference MUST be a full normal standard windows path name!!!
so, if say your vb.net code was to "test" if the above file existed?
Lets say we drop a button and a image control on a web page - we have this:
and lets just make this super simple - we want in vb code to set the above image control to a picture we have in our Content folder.
Well, you have to translate the web based url into a plane jane good old fashioned windows file path name!
So, you would do this:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strF As String
strF = "~/Content/uncheck1.jpg"
Dim strFInternal = Server.MapPath(strF)
Debug.Print(strFInternal)
If File.Exists(strFInternal) Then
Image1.ImageUrl = strF
End If
End Sub
Note how our INTERNAL code MUST use a good old plane jane windows file path name.
but for things on the web page? They are ALWAYS referenced from the point of view of the web site. After I run the above code I get this:
But that debug.print of the file name? This is the output:
Output:
C:\Users\AlbertKallal\source\repos\WebFriendlyTest\Content\uncheck1.jpg
Note VERY careful the above? It was a plane jane INTERNAL file name. I can't tell you how many times I struggled with above simple concept:
Web page controls and markup: use correct URL path names
Code behind: use full windows path name!!!
So, your posted code? it WILL work near as it stands!!!!
The only issue here is what folder you looking to push out to that list box?
Say in above, I wanted to push out ALL files in that Content Folder.
I mean, I can type in this to display that check box if I wanted to:
So the web page now displays that one simple image on the page - since I typed in the FULL correct url!!!
So, how about we drop a list box on the web form, and when we click our button, we display ALL files in that Content folder. Now I could "guess" the location of the file folder, but for ANY WEB page to use that folder, it HAS to be part of the web site folders (or sub folders). The web site can NOT just out of the blue map to steal or grab ANY file on the computer - those URL's can ONLY point to say root of the site + any sub folder.
So that content folder on this site is this:
So, as you can see, then I can type in a url that is the base site, and then that folder, and then that picture (uncheck1.jpg) that exists in that folder.
So, lets drop in a listbox, and push out all the files from that folder to the listbox on the form:
Our markup will be this:
So, just a button, and a list box.
And the button code for the Content folder? Well, we would use this:
(I removed the search part - but that is standard code - JUST like you ALWAYS used in the past!!!
So:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim MainFldr = "~/Content"
Dim FldrInternal = Server.MapPath(MainFldr)
Dim SKfiles() As System.IO.FileInfo
Dim FldrInfo As New System.IO.DirectoryInfo(FldrInternal)
ListBox1.Items.Clear()
SKfiles = FldrInfo.GetFiles("*.*", IO.SearchOption.AllDirectories)
For Each MyFile In SKfiles
ListBox1.Items.Add(MyFile.Name)
Next
End Sub
I decided to NOT use the full path name - but I could have.
The output:
so just remember, that any web page? It can ONLY use files and things that are PART of the web site. And any url - even for a picture, file etc.? Then it MUST be a valid URL.
However, the code behind? It is NOT limited to JUST the folders and files from the root and sub folders. You can actually use your d: drive, or anything else that box on the network can get/grab/use/fetch. So the code behind is your plane jane windows code.
The web site URL and files from web pages thus can only use folders/files that are part of the web site. However, in some cases, say you had some other big server with folders for pictures and files - but your web site (and valid URL's) need to use that folder? Well, you then setup what is a called a virtual directory. This you quite much need to use IIS as opposed to using IIS express edition. (you can google for express edition + setup virutal folders).
Once that virtual folder is setup? It will look like any other sub folder in teh site - but they are not in the site anymore. (and this is also used for documents or PDF folders often too).
This is simply LOOKS like a sub folder, but it really is a folder that can point to any other folder on your computer network. of course this would only work if the final web server and published site location is running on a box on your server, and say not some hosting plan.
So one should code and NOT think in terms of full valid local server file names, but try to always think in terms of the URL, and the path name, and even path names in sub folders in that web site. But in all cases, the code behind operations are against plane jane valid full path names.
However, if you thought that debug.print of the simply .jpg file name was long or funny? Well, on a published server those file path names can be super crazy paths - but you NEVER care if you reference the folders as per above.

I solve the problem by creating search like below. searching folder name and subfolder.
Dim files As FileInfo() = Nothing
Dim dirInfo As DirectoryInfo = New DirectoryInfo(startFolder)
Dim dir As DirectoryInfo() = Nothing
dir = dirInfo.GetDirectories(folderName, SearchOption.AllDirectories)
For i = 0 To dir.Length - 1
If dir(i).Name = folderName Then
Dim path2 = Directory.GetDirectories(dir(i).FullName)
If path2.Length = 0 Then
files = dir(i).GetFiles()
For Each file In dir(i).GetFiles()
path = CStr(dir(0).FullName)
path = path.Remove(0, 11)
HiddenField1.Value = path & "\" & file.Name
HiddenField2.Value = file.Name
Dim tr As New TableRow
tr.Cells.Add(New TableCell With {.Text = file.Name})
grd.Rows.Add(tr)
Dim tdlnk As New TableCell
Dim lnk As New HtmlAnchor
tdlnk.Controls.Add(lnk)
tr.Cells.Add(tdlnk)
Next
Exit For
Else
Dim aaa As String = path2(0).Substring(path2(0).Length - 10)
startFolder = path2(0).ToString
folderName = aaa
Dim files1 As FileInfo() = Nothing
Dim dirInfo1 As DirectoryInfo = New DirectoryInfo(startFolder)
Dim dir1 As DirectoryInfo() = Nothing
dirInfo1.GetDirectories(folderName, SearchOption.AllDirectories)
files1 = dirInfo1.GetFiles
For Each file In dirInfo1.GetFiles
path = CStr(dirInfo1.FullName)
path = path.Remove(0, 11)
HiddenField1.Value = path & "\" & file.Name
HiddenField2.Value = file.Name
Dim tr As New TableRow
tr.Cells.Add(New TableCell With {.Text = file.Name})
grd.Rows.Add(tr)
Dim tdlnk As New TableCell
Dim lnk As New HtmlAnchor
tdlnk.Controls.Add(lnk)
tr.Cells.Add(tdlnk)
Next
Exit For
End If
End If
Next

Related

Server.MapPath changes file path when passed outside of Class

I abbreviated my code here and hope convey enough data to express the problem I am having. I am more than happy to elaborate as needed.
Background:
I have an asp site that has about 70 pages that open files from various locations.
In one scenario I do some file manipulation, like copy, rename, convert to PDF etc.
This is done my moving the file into the project and then eventually serving the file from a project folder.
Originally I created a class with a few functions.
I call the function from the web page and the class manipulates and then opens the file.
Dim ReturnValue As String = OpenMyFile.OpenQCBD(Doc_Id)
The function would manipulate the file and the open it (note the creation of the file path)
OpenTempFile(HttpContext.Current.Server.MapPath(fpath & "\") & FileName.ToLower, FileName)
Then opens it (contained in the class)
Public Sub OpenTempFile(strURL As String, FileName As String)
Dim req As WebClient = New WebClient()
Dim response As HttpResponse = HttpContext.Current.Response
response.Clear()
response.ClearContent()
response.ClearHeaders()
response.Buffer = True
response.AppendHeader("Content-Disposition", "attachment; filename=""" & FileName & """")
response.WriteFile(strURL)
response.Flush()
response.SuppressContent = True
HttpContext.Current.ApplicationInstance.CompleteRequest()
This all worked great and passed the proper file path and opened the file (e.g. \\MyServer\Folder...) This was tested both locally and in production and worked as expected.
I had to make a change and pass the file path back to the asp page and then call the procedure to open the file from there.
Class the function from asp page (same)
Dim ReturnValue As String = OpenMyFile.OpenQCBD(Doc_Id)
Instead of opening the file return the file path
Result = HttpContext.Current.Server.MapPath(fpath & "\") & FileName.ToLower
And then open the file (call from asp page)
OpenMyFile.OpenTempFile(FilePath, Path.GetFileName(FilePath))
This works great running locally on my machine.
However when I run it from the production server the class function returns C:Folder/.. instead //server/folder/... like it did before.
Construction of the file path is the same in both scenarios.
OpenTempFile(HttpContext.Current.Server.MapPath(fpath & "\") & FileName.ToLower, FileName)
vs
Result = HttpContext.Current.Server.MapPath(fpath & "\") & FileName.ToLower
The only difference is passing it back to the asp page, this is where I receive the wrong path.
Again - works fine on my local machine
Any help or direction would be super helpful, thanks in advance.

Image.FromFile "File Not Found" when File is there

I have a file stored in a directory within my site. When I attempt to access the file using image.fromfile, an exception is thrown saying that the file is not there. However, when I access the exact same file using the exact same path but loading it into an image control, the image loads flawlessly verifying that it is there.
The code that throws the file not found exception is:
Private Sub btnCombine_Click(sender As Object, e As EventArgs) Handles btnCombine.Click
Dim BMCanvas As Bitmap 'the "canvas" to draw on
Dim BackgroundTemplate As Image 'the background image
Dim img1Overlay As Bitmap 'the character image
BackgroundTemplate = Image.FromFile("~/Account/Images/Blue 1-02.jpg") 'Template Background Image
img1Overlay = Image.FromStream(FileUpload1.FileContent) 'First overlay image
BMCanvas = New Bitmap(500, 647) 'new canvas
Using g As Graphics = Graphics.FromImage(BMCanvas)
g.DrawImage(BackgroundTemplate, 0, 0, 500, 647) 'Fill the convas with the background image
g.DrawImage(img1Overlay, 50, 50, 100, 100) 'Insert the overlay image onto the background image
End Using
'Setup a path to the destination for the composite image
Dim folderPath As String = Server.MapPath("~/OutFiles/")
'Create a directory to store the composite image if it does not already exist.
If Not Directory.Exists(folderPath) Then
'If Directory (Folder) does not exists Create it.
Directory.CreateDirectory(folderPath)
End If
'Temporarily save the file as jpeg.
BMCanvas.Save(folderPath & "Temp1.jpg", Imaging.ImageFormat.Jpeg)
'View the resulting composite image in image control.
Image1.ImageUrl = folderPath & "Temp1.jpg"
BMCanvas.Dispose()
End Sub
And the code that verifies that the image is in-fact in the directory and successfully displays the image is:
Private Sub cboRole_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboRole.SelectedIndexChanged
If cboRole.SelectedIndex = 1 Then
Image1.ImageUrl = "~/Account/Images/Blue 1-02.jpg"
End If
End Sub
I cannot figure out why one way works and the other way does not.
I have also tried the following code without success:
'Another way to read the image files
Image = File.ReadAllBytes(Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "~/Account/Images/Blue 1-02.jpg")))
OK, the answer to second part of your question (the "Why it's working with ImageUrl?") is located in documentation
Quote:
Use the ImageUrl property to specify the URL of an image to display in
the Image control. You can use a relative or an absolute URL. A
relative URL relates the location of the image to the location of the
Web page without specifying a complete path on the server. The path is
relative to the location of the Web page. This makes it easier to move
the entire site to another directory on the server without updating
the code. An absolute URL provides the complete path, so moving the
site to another directory requires that you update the code.
It (the Image control) already has embedded feature of "Mapping" the path relatively to your web page folder.
When using path from within your code, without controls, like in Image.FromFile, you need to make sure path is correctly mapped, by using Server.MapPath
As you already did in your code for Directory creation.
You cannot have an Image from a relative url.
To get your Image as an System.Drawing.Image you need to get them from a physical path like this (in your case)
Dim image As System.Drawing.Image = System.Drawing.Image.FromFile(HttpContext.Current.Request.PhysicalApplicationPath & "\Account\Images\Blue 1-02.jpg") 'Server.MapPath("~/Account/Images/Blue 1-02.jpg"))

DotNetZip download works in one site, not another

EDIT - RESOLVED: the difference was that in the "main" case the download was initiated via a callback cycle, and in the "test" case it was initiated through a server side button click function. My guess is that the download request and the callback cycle interfered with each other, both stopping the download and causing the page to become inactive (as described below). When I rewired the download on the main page to start with a submit instead of a callback, it did initiate the download.
This is in VS2013 Ultimate, Win7Pro, VB.Net, websites (not projects),IISExpress.
I built a test site to develop functionality for creating OpenXML PPTX and XLSX memorystreams and zipping and downloading them using DotNetZip. Got it to work fine. I then merged all that code into my "main" site. Both sites are on the same machine; I can run the test site and the main site at the same time. The main site processing is somewhat more complicated, but only in terms of accessing and downloading more files.
However, the Zip and Download function (below) works fine in the test site, but the exact same code doesn't work in the main site (with or without the test site up and running).
There's an error trap (see below) around the Zip.Save function where the download occurs but no error shows up.
Same overall behavior in Chrome, Firefox and IE11.
One peculiarity that might be a clue is that when the main site download fails, the server side functionality "goes dead". Local JS functions work, but the app doesn't respond to callbacks. When I do an F5 on the browser it works again.
I did a refresh on the DotNetZip package in the main site. The Zip object appears to be working properly, because it generates an error on duplicate file names.
I thought it might be the download function as written, however, it works in the test site. Also, another piece of the main site does a non-zipped download of a memory stream (included as the second code block below) and that works fine.
I thought it might be the data. So I kludged the main site to access, convert to memorystream and download the same file that the is accessed and downloaded in the test site. Still the main site download doesn't work.
When I compare the watch values on the Zip object in the two sites, they look identical. The length of the wrkFS.ContentStream is identical in both cases. The file names are different, however, they are:
Test_2EFVG1THK5.xlsx (main)
6-18_12-46-28_0.xlsx (test)
which are both legal file names.
EDIT: I saved the zip file to disk from the main program, instead of trying to download it, using this:
wrkFilePath = "D:\filepath\test.zip"
wrkZip.Save(wrkFilePath)
And it worked fine. So that possibly isolates the problem to this statement
wrkZip.Save(context.Response.OutputStream)
EDIT: Base on help I received here:
Convert DotNetZip ZipFile to byte array
I used this construct:
Dim ms as New MemoryStream
wrkZip.Save(ms)
wrkBytes = ms.ToArray()
context.Response.BinaryWrite(wrkByteAr)
to get around the ZipFile.Save(to context), and that didn't work either; no download, no error message, and page goes dead. However, at least I can now assume it's not a problem with the ZipFile.Save.
At this point I'm out of ways to diagnose the problem.
Any suggestions would be appreciated.
Here is the code that works in the test site but not in the main site.
Public Sub ZipAndDownloadMemoryStreams(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim rtn As String = ""
Try
Dim wrkAr As ArrayList
wrkAr = SC.ContentArrayForDownLoad
If wrkAr.Count = 0 Then
Dim wrkStop As Integer = 0
Exit Sub
End If
Dim wrkFS As ZipDownloadContentPair
Using wrkZip As New ZipFile
'----- create zip, add memory stream----------
For n As Integer = 0 To wrkAr.Count - 1
wrkFS = wrkAr(n)
wrkZip.AddEntry(wrkFS.FileName, wrkFS.ContentStream)
Next
context.Response.Clear()
context.Response.ContentType = "application/force-download"
context.Response.AddHeader( _
"content-disposition", _
"attachment; filename=" & "_XYZ_Export.zip")
'---- save context (initiate download)-----
wrkZip.Save(context.Response.OutputStream)
wrkZip.Dispose()
End Using
Catch ex As Exception
Dim exmsg As String = ex.Message
Dim wrkStop As String = ""
End Try
End Sub
Below is the non-zip download function that works fine in the main site.
It might be possible to convert the Zip content to a byte array and try the download that way, however, I'm not sure how that would work.
(SEE EDIT NOTE ABOVE --- I implemented a version of the below, i.e. try to download byte array instead of directly ZipFile.Save(), however, it didn't help; still doesn't download, and still doesn't give any error message)
Public Sub DownloadEncryptedMemoryStream(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim wrkMemoryStream As New System.IO.MemoryStream()
wrkMemoryStream = SC.ContentForDownload
Dim wrkFileName As String = SC.ExportEncryptedFileName
wrkMemoryStream.Position = 0
Dim wrkBytesInStream As Byte() = New Byte(wrkMemoryStream.Length - 1) {}
wrkMemoryStream.Read(wrkBytesInStream, 0, CInt(wrkMemoryStream.Length))
Dim wrkStr As String = ""
wrkStr = Encoding.UTF8.GetString(wrkMemoryStream.ToArray())
wrkMemoryStream.Close()
context.Response.Clear()
context.Response.ContentType = "application/force-download"
context.Response.AddHeader("content-disposition", "attachment; filename=" & wrkFileName)
context.Response.BinaryWrite(wrkBytesInStream)
wrkBytesInStream = Nothing
context.Response.End()
(Per the note now at the top of the question): The difference was that in the "main" case the download was initiated via a callback cycle, and in the "test" case it was initiated through a server side button click function. My guess is that the download request and the callback cycle interfered with each other, both stopping the download and causing the page to become inactive (as described below). When I rewired the download on the main page to start with a submit instead of a callback, it did initiate the download.

Read source of popup windows opened with javacript:void()?

I am going to do my best to ask this question as clearly as possible. Is it possible to write some asp.net code that can go through and read the source of pop up windows that are normally opened by clicking a javascript:void() link. Basically i want to read the source of said popups, extract specific links and then render those links in a web page. What i am trying to achieve is a way to make it easy to download the videos of the Senate floor - their videos open in a new popup that uses silverlight. The mp4 file location is in the source so i want to read that url. I did something similar using the code below. The difference was that the mp4 links were in main page. The code read the source and then outputted the video links so i could just right click and do a save as. This was for the videos at the German security conference. Apologies if this is not seen as a constructive question and ends up being closed.
Protected Sub btnClick_Click(sender As Object, e As EventArgs) Handles btnClick.Click
Dim r As New Regex("\bhttps?://\S+\.(?:jpg|png|gif|mp3|mp4|3gp)\b", RegexOptions.IgnoreCase)
Dim c As New WebClient
Dim s As String = c.DownloadString(txtUrl.Text)
Dim sb As New StringBuilder
For Each m As Match In r.Matches(s)
sb.Append("" & m.Value & "<br />")
divLinks.InnerHtml = sb.ToString
Next
End Sub

databind a DropDownList control with a list of all sub directories that exist in a particular directory on the server

I am wanting to databind a DropDownList control with a list of all sub directories that exist in a particular directory on the server. The directory I want to search is in the root of the application. I am fairly new to programming and I'm not sure where to even start.
I found this code on a website:
Dim root As String = "C;\"
Dim folders() As String = Directory.GetDirectories(root)
Dim sb As New StringBuilder(2048)
Dim f As String
For Each f In folders
Dim foldername As String = Path.GetFileName(f)
sb.Append("<option>")
sb.Append(foldername)
sb.Append("</option>")
Next
Label3.Text = "<select runat=""sever"" id=""folderlist""" & sb.ToString() & "</select>"
I guess this is vb. but my tool is in asp, so is their something similar in vbscript so that I can use it.
Here is a very quick and dirty example of what you want.
There are a lot of improvements I would make before I'd consider it production ready code.
It should however server to show you some of the basic concepts you are after.
<%# Language=VBScript ENABLESESSIONSTATE = False%>
<select id="selFiles" name="selFiles" class="Select" style="width: 250px" tabindex="130">
<%
Dim fso, folder, files
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder("C:\")
Set files = folder.Files
For each folderIdx In files
Response.Write("<option>" + folderIdx.Name + "</option>")
Next
%>
</select>
One place to start looking at improvements here would be introducing your own components that will do all the complex stuff like listing files this gives you more control, allows greater modularity in you design and (probably most importantly) gives you better control of security.
The information below may be slightly off (it is from memory of an old project) but should be reasonably close and give you a start on introducing code components into your ASP classic code.
With ASP classic you create objects using code like:
<object runat="server" progid="YourObject.Class" id="oObject" VIEWASTEXT></object>
Where YourObject.Class is the programatic id of a component installed in the registry.

Resources