views:

388

answers:

4

What would be the best method to implement the following scenario: The web site calls for a image gallery that has both private and public images to be stored. I've heard that you can either store them in a file hierarchy or a database. In a file hierarchy setup how would prevent direct access to the image. In a database setup access to the images would only be possible via the web page view. What would be a effective solution to pursue?

[Edit] Thanks all for the responses. I decided that the database route is the best option for this application since I do not have direct access to the server. Confined to a webroot folder. All the responses were most appreciated.

+1  A: 

In reality both scenarios are very similar, so it's up to you... Databases weren't designed to serve files, but if the size isn't really a concern for you, I don't see a problem with doing it.

To answer your question about direct access, you'd setup the file images the same way you would for the database: You'd use some sort of page (probably a .ashx handler) that serves the images, allowing you a layer of logic between the user and image to determine whether or not they should have access to it. The actual directory the images are located in would then need to either a) not be part of the directory structure in IIS or b) if it is part of IIS, only allow windows authenticated access, and only allow the account the application process is running under access to the directory.

John
If you are in a load balanced environment though, you will want to either have a server designated as a resource server, or create some sort of duplication mechinism between the servers.
andrewWinn
+1  A: 

Using file hierarchy, you can put the files out of the website file folder, for example, suppose the web folder is c:/inetpub/wwwroot/somesite, put the file under c:/images/, so that the web users won't be able to access the image files. but you cannot use the direct link in your website neither, you need to create some procedure to read the file, return the stream.

personally I think it's better to put the file in the database, still create some procedure to retrieve the binary image data and return to wherever it needed.

Estelle
I was going to up vote this comment until you stated that you think it is better to put the file in the database :-\ if you have lots of images stored in the database, it can cause serious performance issues.
andrewWinn
I understand there is a limitation. but by my own experience, the sql server handles it pretty well... :-)
Estelle
Andrew, see my comment re: FILESTREAM storage - that addresses the performance concern
Dan Diplo
A: 

If you're using IIS7, since .net jumps in the pipeline early I believe you can protect jpg files as well, just by using a role manager and applying roles to file system folders. If you're using IIS6, I've done something similar to the answer by John, where I store the actual file outside of the wwwroot, and use a handler to decide if the user has the correct credentials to view the image.

I would avoid the database unless you have a strong reason to do this - and I don't think a photo gallery is one of them.

ScottE
+1  A: 

Having used both methods I'd say go with the database. If you store them on the filestore and they need protecting then you'd have to store them outside the web-root and then use a handler (like John mentions) to retrieve them, anyway. It's as easy to write a handler to stream them direct from database and you get a few advantages:

  • With database you don't need to worry about filestore permissions or generating unique filenames or folder hierarchies etc.
  • With database you can easily apply permissions and protection directly - no trying to work out who can view what based on paths etc.
  • With a database you can store the image and metadata all together - when you delete the metadata you delete the image - no possibility of orphaned records where you delete from database but not from filestore
  • Easier to back-up database and images and then restore

The disadvantage is that of performance, but you can use caching etc. to help with that. You can also use FILESTREAM storeage in SQL Server 2008 (and 05?) which means you get filesystem performance but via the DB:

"FILESTREAM integrates the SQL Server Database Engine with an NTFS file system by storing varbinary(max) binary large object (BLOB) data as files on the file system. Transact-SQL statements can insert, update, query, search, and back up FILESTREAM data. Win32 file system interfaces provide streaming access to the data.

FILESTREAM uses the NT system cache for caching file data. This helps reduce any effect that FILESTREAM data might have on Database Engine performance. The SQL Server buffer pool is not used; therefore, this memory is available for query processing."

Dan Diplo