There is more than one way to store images that your web site will display. The project I am working on is to change the current logic that stores the image as a blob in our database. I looked at SQL Server 2008’s filestream datatype, but decided against using it because one of the new requirements was to be able to move the images to a new server in the near future. And we also wanted to be able to reference the images directly to facilitate browser caching and concurrent requests to the images. This blog shows the solution I used.
The first thing is what exactly to store in the database. My initial thought was to store a URL relative to the virtual folder as the path, but decided to just store the image name. My reasoning here is that the directory structure could change and we wouldn’t have to back and update the database. I am also storing the original file name in the database and the mime type.
So then, how do you name the new image? Use Path.GetRandomFileName()? Or use DateTime.Now.Ticks? Or use a Guid? What I ended up doing is simply using the file’s MD5 hash. This has the advantage of either being able to limit the user’s ability to upload the exact image more than once, or you can allow the upload, but you don’t save the duplicated file. Both database records point to the same location, thus saving space on your image server.
1: var ext = new FileInfo(uplaodedName).Extension;
2: // use md5 hash as file name to prevent duplicate images being uploaded
3: var md5 = MD5.Create();
4: var hash = md5.ComputeHash(imageBytes);
5: // user token encode to +, / and = characters
6: // are substituted for other tokens to make URL safe
7: var fileName = HttpServerUtility.UrlTokenEncode(hash) + ext;
8:
9: var relPath = string.Format("{0}/{1}/{2}/", DateTime.Now.Year,
10: DateTime.Now.Month, userName);
11: var fullPath = Path.Combine(basePath, relPath, fileName);
12:
13: if (_directory.Exists(fullPath))
14: {
15: var fi = new FileInfo(fullPath);
16: // make sure folder exists
17: if (!_directory.Exists(fi.Directory.FullName))
18: {
19: _directory.CreateDirectory(fi.Directory.FullName);
20: }
21: _file.WriteAllBytes(fullPath, imageBytes);
22: }
23:
24: myImage.Save(fileName);
25: