to create a gallery in asp.net by iterating through the folders - c#

I want to create a gallery in asp.net the way it should work is as follows:
iterate through gallery folder
select all the folder and show them as albums with cover pic as thumbnail.jpg in that folder
when clicked on the album it should display the content of the folder (images).
My approach for creating this was to iterate through the folders and make views and link button based on that for albums and to display the content of album in that view as images using repeater control, but that didn't work out as it had many errors while implementing it. and I had to write the whole thing in on_init() function because of dynamic views.I can implement the html and js part (like for light box and other visual stuffs).
Please suggest some better approach maybe with some code example. Please use c# . Thanks

I can not just write you all the code... but ill give you a startup code:
int scanLVL = 4;//or however deep you need to go...
public void GetImageFromDir(string sourceDir, int startLVL)
{
if (startLVL <= scanLVL)
{
// Here you can process files found in the directory.
string[] fileEntries = Directory.GetFiles(sourceDir);
Label_showdata.Text +="<br />Dir:" + Path.GetFileName(sourceDir) ;
foreach (string fileName in fileEntries)
{
// do something with fileName
String tree = "";
for (int i = 0; i < startLVL; i++)
tree += " ";
Label_showdata.Text += "<br />" + tree + Path.GetFileName(fileName);
}
// Going in subdirectories of this directory.
string[] subdirEntries = Directory.GetDirectories(sourceDir);
foreach (string subdir in subdirEntries)
if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
GetImageFromDir(subdir, startLVL + 1);
}
}
This will print you on your web page(actualy in that Label_showdata) all the files and the directory where they are.
Basically from here you will need to wrap that data into a table and bind it in whatever control you feel comfortable with... Is not that hard actually... but it takes a bit more time to write exactly all the code (time that unfortunatlly i do not have at the moment...)

Related

Error while trying to rename files using C#

I have the following code to rename files in the following tree as from 00000001.pdf to the last file with this 8 character left padding, e.g: 00000100.pdf
Folder1
subfolder1
childfolder1
pdffile1
pdffile2
childfolder2
pdffile3
pdffile4
subfolder2
childfolder3
pdffile5
pdffile6
But for some reason in some of those child folders it keeps renaming them with no end.
Some times it just jumps to another number, as if it was an async operation. But if I stop and start again it goes okay until the second next folder, when it messes up again.
But this error only happened within 19 folders.
Indeed their pdf names are different from the others, but I don't see how it is related.
The other files were named something like "DOCUMENT_01" and so on, but these are:
0000000100000001.pdf
0000000200000001.pdf
0000000300000001.pdf
etc
static void Main(string[] args)
{
Console.WriteLine("Digite a pasta 'pai' onde serão buscados pdfs dentro das pastas 'filhas':");
string path = Console.ReadLine();
foreach (string dir in Directory.EnumerateDirectories(path))
{
foreach (string subdir in Directory.EnumerateDirectories(dir))
{
Console.WriteLine($"{dir} - {subdir}");
int n = 1;
foreach (string pdffile in Directory.EnumerateFiles(subdir, "*.pdf", SearchOption.AllDirectories))
{
Console.WriteLine(n.ToString().PadLeft(8, '0') + " " + new FileInfo(pdffile).Length);
File.Move(pdffile, subdir + $"\\{n.ToString().PadLeft(8, '0')}.pdf");
n++;
}
Console.WriteLine("\n\n");
}
}
}
What could be going wrong?
It should await for the File.Move method to end to add the n + 1 and then moving to the next pdffile as a synchronous operation. So why does it jumps numbers after a random time and why it keeps going forever other times?
And just to remember, if I stop the program and start again and put the folder that was messed up as the first one, it goes ok and only when it goes to the next folder, or the folder after next that it start to give me this error again.
Hope that I could make myself clear... Thanks for your attention!
EDIT: will try using FileInfo class to give me the parent folder with the SearchOption.AllDirectories option and exclude this 3 stage loop plus actually working for any kind of tree structure
EDIT2: Tried, worked as a "tree indepent" script but getting the same result with the files name after the first folder... As it's really fast, in 3 seconds it goes from 00000169.pdf to 00006239.pdf in a folder with just 330 items.
As commented already, it is not a good idea to move or rename files “WHILE” the code is enumerating though the list of those files as the posted code appears to do. This will cause obvious problems and you should simply mark the files somehow, then later come back and rename or move them.
More importantly, the big issue related to renaming/moving files is exactly as you describe with your current issue. The problem is that the errors are erratic and not consistent. Making it very difficult to trace. However, the problems you describe are classic trademarks of moving/renaming files while enumerating through those files.
With that said, the best way and easiest way to traverse an unknown number of folder levels given a starting folder is by using recursion. In a lot of cases, recursion can be avoided with some well though out loops, however when we do not know how many levels of folders there are, then, using a simple loop or foreach loop paradigm may be doable, however, you will most likely be adding variables and code that only makes this more complex. This is shown in the current code with the addition of the dir variable to keep track of “when” a different folder is used. Recursion is suited ideally for this situation.
In this case, this recursive method will be called ONCE for each folder and subfolders from a given “starting” folder location. This means that each time this recursive method is called is when a different folder is beginning to be processed. So n would always start at 1 and we do not need to keep track of the current folders path.
So the signature of this method will take a DirectoryFolder object as a “starting” folder. First we create some variables; a FileInfo array pdffiles to hold the pdf files in the given folder; in addition to a DirectoryInfo array foldersInThisFolder to hold all the other folders in this starting folder. Lastly an int n to index the files as the posted code is doing.
Next we get all the pdf files in this “starting” folder. If there are pdf files in this folder, then we loop through those files and process them. Next, we get all the other folders in this “starting” folder. Then start a loop through each folder. For each folder in this collection we will make the recursive call back to this method using the next folder as the “starting” folder, then the whole process continues until the loop through those folders ends.
static void TraverseDirectoryTree(DirectoryInfo startingFolder) {
FileInfo[] pdffiles = null;
DirectoryInfo[] foldersInThisFolder = null;
int n = 1;
Console.WriteLine(startingFolder.FullName);
// get all the pdf files in this folder
try {
pdffiles = startingFolder.GetFiles("*.pdf");
}
catch (Exception e) {
// you may want to catch specific exceptions
// however in this example we do not care what
// the exception is, we will simply ignore this.
// in most cases pdffiles will be null if an exception is thrown
Console.WriteLine(e.Message);
}
if (pdffiles != null) {
foreach (FileInfo pdffile in pdffiles) {
Console.WriteLine(pdffile.FullName + " -> " + n.ToString().PadLeft(8, '0') + " " + pdffile.Length);
//File.Move(pdffile.FullName, pdffile.DirectoryName + $"\\{n.ToString().PadLeft(8, '0')}.pdf");
// add file path to a list of files to rename later?
n++;
}
// start over wiith the sub folders in this folder
foldersInThisFolder = startingFolder.GetDirectories();
foreach (DirectoryInfo dirInfo in foldersInThisFolder) {
TraverseDirectoryTree(dirInfo);
}
}
}
Usage…
Console.WriteLine("Type the folder you want to start with:");
string path = Console.ReadLine();
DirectoryInfo di = new DirectoryInfo(path);
TraverseDirectoryTree(di);
Edit… after further testing it appears that what you are wanting to do is simply “rename” the pdf files. As suggested a simple solution is to save the files that we want to rename, then, after we collect the files we want to rename, we simply loop through those files and rename them. This should eliminate any problems by renaming files while enumerating though the files collection.
To help, I created a Dictionary<string, int> called filesToRename. While recursively looping through all the folders, we will add the full path of each pdf file we want to rename as the Key and the int value n as the Value. After the dictionary is filled we would simply loop through it and rename the files.
private static Dictionary<string, int> filesToRename = new Dictionary<string, int>();
Then replace the commented-out line in the recursive method TraverseDirectoryTree…
//File.Move(pdffile.FullName, pdffile.DirectoryName + $"\\{n.ToString().PadLeft(8, '0')}.pdf");
With…
filesToRename.Add(pdffile.FullName, n);
Then after the dictionary is filled we would loop through it and rename the files, something like…
DirectoryInfo di = new DirectoryInfo(path);
TraverseDirectoryTree(di);
foreach (KeyValuePair<string, int> kvp in filesToRename) {
int index = kvp.Key.ToString().LastIndexOf(#"\");
string dir = kvp.Key.ToString().Substring(0, index);
File.Move(kvp.Key, dir + $"\\{kvp.Value.ToString().PadLeft(8, '0')}.pdf");
}
I am hoping this makes sense…
Answer as Klaus Gütter helped me, I just added .ToList() to the Directory.EnumerateFiles so it made a fixed list first, and then made the foreach for each file
It will rename every pdf within the folder and it's subfolders
Console.WriteLine("Type the folder you want to start with:");
string path = Console.ReadLine();
string dir = "";
int n = 1;
foreach (string pdffile in Directory.EnumerateFiles(path, "*.pdf", SearchOption.AllDirectories).ToList())
{
FileInfo fi = new FileInfo(pdffile);
if (fi.DirectoryName == dir)
{
Console.WriteLine("\t" + n.ToString().PadLeft(8, '0'));
File.Move(pdffile, dir + $"\\{n.ToString().PadLeft(8, '0')}.pdf");
n++;
}
else
{
n = 1;
dir = fi.DirectoryName;
Console.WriteLine("\n\n" + dir);
File.Move(pdffile, dir + $"\\{n.ToString().PadLeft(8, '0')}.pdf");
Console.WriteLine("\t" + n.ToString().PadLeft(8, '0'));
n++;
}
}

Retrieve a list of files stored in a folder into my solution ASP.NET

I am not sure if I am in the right place to ask this, I am trying to create a table with all the PDF files that I have in a folder into my solution.
And I am trying to retrieve their names and put them in a table to access all of them throughout a link.
I got the following method, however, it not working.
protected void ListFiles()
{
const string MY_DIRECTORY = #"~/HistoricalFiles";
string strFile = null;
foreach (string s in Directory.GetFiles(Server.MapPath(MY_DIRECTORY), "*.*"))
{
strFile = s.Substring(s.LastIndexOf("\\") + 1);
//ListBox1.Items.Add(strFile);
}
}
Is there any way I can access all of them easily and display them in a good way?
By looking at your image, you should change the path of the folder. It is not in your root directory, it is inside Reports\API folder
const string MY_DIRECTORY = #"~/Reports/API/HistoricalFiles";

.NET/C# How to render static HTML from a separate folder with relative referenced content

I'm developing a custom CMS. I have content per ResearchArticle stored in Azure blobs. The content consists of an index.html file with any related images, pdf's etc. the index.html page uses relative local references as in:
<img src="chuck-norris-1.jpg" />
This is so our designer can make articles with related content and put it all in one folder to be sent to an Azure blob container. Each web server then downloads the content into a local ResearchArticle content folder structure as in:
ResearchArticleBodyLocal\abc
So, now I have to display this content when someone views the article. I was reading the index.html into a string and using #Html.raw(). Problem is, from the view, the relative references aren't working because the view, obviously, is in a different location than the content.
but #1 the relative references are off, and #2 for some reason it's running the action method twice as if it has a jQuery problem, but I'm not using any JQuery here...
Here's what I'm trying:
controller method-
ravm.ArticleBodyIndexHtmlPath = System.IO.File.ReadAllText(Server.MapPath(ConfigurationManager.AppSettings["ResearchArticleBodyRelativeLocalDirectory"] + researchArticle.BodyRelativeLocalPath + "/index.html"));
View -
#(Html.Raw(Model.ArticleBodyIndexHtmlPath))
I've also tried this solution but the relative reference thing is still a problem... Anyone have a vision of how to solve this without having the designer put the intended directory structure into the content references?
You could perhaps put the directory structure there using a bit of string replacement/regex? I do that within my own templating system so that the designer can do src="chuck-norris.jpg" and I replace it depending on the site being hit with src="/othersite-image-dir/chuck-norris.jpg" automatically. That way my designer doesn't have to remember directories.
The other way around it is to have a specific directory structure for your objects, i.e
images
js
css
That way the designer can go src="/js/my-chuck-norris.js" and always hit the file regardless of which site it's in
Yes, I wound up doing this:
private List<string> GetFilePathsAndUpdateIndexHtml(string bodyFolderChoices, string containerName)
{
// get path to each item
var filePaths =
Directory.GetFiles(
Server.MapPath(ConfigurationManager.AppSettings["ResearchArticleFTPUploadRoot"] + "/" +
bodyFolderChoices));
// get root from web.config
var azureRootUrl = ConfigurationManager.AppSettings["AzureBlobRootUrl"] + containerName + "/";
// find index.html and replace relative references
foreach (var s in filePaths)
{
if (s.Contains("index.html"))
{
var doc = new HtmlDocument();
doc.LoadHtml(System.IO.File.ReadAllText(s));
HtmlNodeCollection links = doc.DocumentNode.SelectNodes("//*[#background or #lowsrc or #src or #href]");
if (links == null)
continue;
foreach (HtmlNode link in links)
{
// references to outside URLs this will break unless we check for 'http' and leave alone
if (link.Attributes["background"] != null && !link.Attributes["background"].Value.Contains("http"))
link.Attributes["background"].Value = azureRootUrl + link.Attributes["background"].Value;
if (link.Attributes["href"] != null && !link.Attributes["href"].Value.Contains("http"))
link.Attributes["href"].Value = azureRootUrl + link.Attributes["href"].Value;
if (link.Attributes["lowsrc"] != null && !link.Attributes["lowsrc"].Value.Contains("http"))
link.Attributes["lowsrc"].Value = azureRootUrl + link.Attributes["lowsrc"].Value;
if (link.Attributes["src"] != null && !link.Attributes["src"].Value.Contains("http"))
link.Attributes["src"].Value = azureRootUrl + link.Attributes["src"].Value;
}
doc.Save(s);
}
}
return filePaths.ToList();
}

open window explorer folder from my results c#

iv made a web forum, as i have lots of folders on my local drive i can now search for any folders i want on webpage.
Now am looking to add a link to the results of the search so it takes me directly to the folder.
My code in c#:
protected void List_Dirs(string searchStr = null)
{
try
{
MainContentLocal.InnerHtml = "";
string[] directoryList = System.IO.Directory.GetDirectories("\\\\myfiles\\Web");
int x = 0;
foreach (string directory in directoryList)
{
if (searchStr != null && searchStr.Length > 1)
{
UserInfo.Text = "Your Search for : <strong>" + SearchPhrase.Text + "</strong> returns ";
if(directoryP.ToLower().Contains(searchStr.ToLower()))
{
MainContentLocal.InnerHtml += directoryP + "<br />";
x++;
}
}
else
{
MainContentLocal.InnerHtml += directoryP + "<br />";
}
if (searchStr != null && searchStr.Length > 1)
{
UserInfo.Text += "<strong>" + x.ToString() + "</strong> results";
UserInfo.CssClass = "userInfo";
}
}
catch(Exception DirectoryListExp)
{
MainContentLocal.InnerHtml = DirectoryListExp.Message;
}
}
When i enter something is search i will get a list of folders like:
Your Search for : project returns 2 results
job234 project234 Awards
job323 project game
now is there any way for me to click the result so i can open a window explore on the webpage
Thanks
You can create links like project234.
string folder = "\\\\myfiles\\Web";
if (string.IsNullOrWhiteSpace(Request["folder"])) {
// Folder clicked
folder = string.Format("{0}{1}", folder, Request["folder"]);
Process.Start(folder);
}
string[] directoryList = System.IO.Directory.GetDirectories(folder);
Then it will open it on the server. So if it really is local, than it will work. If there is no security problem. But I'm not sure. You can also use file:// links (as Ryan Mrachek notes), but browsers are not happy to let you open them.
If your result is a file, you can open that file programmatically through the Process class by invoking Process.Start("C:\\MyResults.txt"). This will open the results in the default text editor. In the same way, you can also open a web page by inserting passing a Url to Process.Start. I hope this is what wanted.
our file urls are malformed. It should be:
file:///c:/folder/
Please refer to The Bizarre and Unhappy Story of File URLs.
This works for me:
link
When you click Link, a new Windows Explorer window is opened to the specified location. But as you point out, this only works from a file:// URL to begin with.
A detailed explanation of what is going on can be found here. Basically this behavior by design for IE since IE6 SP1/SP2 and the only way you can change it is by explicitly disabling certain security policies using registry settings on the local machine.
So if you're an IT admin and you want to deploy this for your internal corporate LAN, this might be possible (though inadvisable). If you're doing this on some generic, public-facing website, it seems impossible.

Uploading Multiple Files to Azure Blob Storage

Pretty new to Windows Azure. I've followed this tutorial: tutorial. It works perfectly however one limitation is that for the application I have in mind, it would need to be possible to upload multiple files relatively quickly.
Is it possible to modify the tutorial to support multi-file uploads, e.g. The user can use shift-click to select multiple files..
Or if anyone knows of any good tutorials detailing the above?
Any help is appreciated,
Thanks
I'd take a look at this tutorial from DotNetCurry which shows how to create a multiple file upload using jQuery to handle the multiple uploading of files to an ASP.NET page. It's built using ASP.NET 3.5, but it shouldn't matter if you're using .NET 4 - there's nothing too crazy going on.
But the key is that the jQuery plug-in will allow you to upload a collection of files to the server. The ASP.NET code behind will handle that by looping through the Request.Files collection:
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
hpf.SaveAs(Server.MapPath("MyFiles") + "\\" +
System.IO.Path.GetFileName(hpf.FileName));
Response.Write("<b>File: </b>" + hpf.FileName + " <b>Size:</b> " +
hpf.ContentLength + " <b>Type:</b> " + hpf.ContentType + " Uploaded Successfully <br/>");
}
}
You would put this code in your tutorial in the insertButton_Click event handler - essentially putting the blob creation and uploading to blob storage inside the above code's if(hpf.ContentLength>0) block.
So pseudo-code may look like:
protected void insertButton_Click(object sender, EventArgs e)
{
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
// Make a unique blob name
string extension = System.IO.Path.GetExtension(hpf.FileName);
// Create the Blob and upload the file
var blob = _BlobContainer.GetBlobReference(Guid.NewGuid().ToString() + extension);
blob.UploadFromStream(hpf.InputStream);
// Set the metadata into the blob
blob.Metadata["FileName"] = fileNameBox.Text;
blob.Metadata["Submitter"] = submitterBox.Text;
blob.SetMetadata();
// Set the properties
blob.Properties.ContentType = hpf.ContentType;
blob.SetProperties();
}
}
Again, it's just pseudo-code, so I'm assuming that's how it would work. I didn't test the syntax, but I think it's close.
I hope this helps. Good luck!

Categories