Retrieving the latest images from a network file share with ASP.NET and JavaScript
What if you have a collection of images stored in a network file share and you want to dynamically show the most recently edited image on a website?
I found myself in this situation when we gradually switched to using .pdfs instead of .tifs for our plan drawings. During this transition, sometimes a newer image would be placed in the same folder with an older image. They would have the same name, but different file extensions. Usually, the newer one would be the PDF, but I couldn’t rely on that to always be the case. So, I needed to check the last modified date to tell which one was the latest official image.
ASP.NET Approach:
I have an ASP.NET application that retrieves these images. Here’s how I did it with C#:
//Check if file exists on the webserver
bool imageFound = false;
string folderName = "nameoffolder";
string fileName = "nameoffile";
string searchFilePath = Path.Combine(@"\\servername\c$\path\to\fileshare\"
+ folderName);
if (Directory.Exists(searchFilePath))
{
//Get the last modified file with the fileName, ignoring the extension
DirectoryInfo directoryInfo = new DirectoryInfo(searchFilePath);
FileInfo selectedFile = directoryInfo.GetFiles(fileName + ".*")
.OrderByDescending(f => f.LastWriteTime).FirstOrDefault();
if (selectedFile != null && selectedFile.Length > 0)
{
imageFound = true;
}
}
This was pretty easy because .NET runs on the server so it has direct access to files there, and there are lots of options built into the codebase for dealing with them. It’s simple to do fancy things like search by filename with a wildcard for the file extension (.*), sort the results descending by the last write time, then pick the first file in the list.
JavaScript Approach:
It is more difficult to do the same thing on the client side. I have another application that needs to search through this same collection of images with JavaScript. The only way for the client to inspect images on the server is by making a request. I do this with the Fetch API for JavaScript.
var src = 'https://URL/to/fileshare/folderName/fileName';
fetch(src + '.tif', { method: 'HEAD' })
.then(function(response) {
if (response.ok) {
var lastmod = response.headers.get('Last-Modified');
var lastmodDate = Date.parse(lastmod);
tifmod = lastmodDate;
}
});
Unlike with C#.NET, I can’t use a wildcard for the extension and get what I need with a single step. Instead, I have to fetch twice, once for each possible extension. Then if the file exists, I save its last modified date to a variable. Finally, I compare all the dates and open the file with the most recent one.
var latestmodDate = Math.max(tifmod, pdfmod);
if (pdfmod == latestmodDate) {
window.open(src + '.pdf', "_blank");
} else if (tifmod == latestmodDate) {
window.open(src + '.tif', "_blank");
}
Since I need to do multiple requests, I was careful to not download the whole image each time, so I’m passing less information over the network. I just look at the headers using the HEAD method (as opposed to the default GET method).
If the images are stored on a different server than your web app, you will need to make sure that the target server is configured to allow the request to go through. You can do this by adding custom HTTP response headers on the Virtual Directory with IIS.
Handling Stale Images:
Finally, web browsers will often cache images after people download them in order to speed up retrieval. We have a nightly process that replaces the images on our web server if there are newer versions. But if a user looked up the same project on the web app two days in a row, yesterday’s image would still be stored in their cache, and they wouldn’t see the new one.
We got around this by appending a timestamp to the end of the image URL.
ImageURL = "https://URL/to/fileshare/folderName/" + selectedFile.Name
+ "?timestamp=" + DateTime.Now.ToFileTime()
Now the browser treats each request as unique, and downloads a fresh version of the image every time.