ASP.NET Image Upload Architecture - asp.net

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.

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."

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.

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.

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.

Neither. Amazon S3 offers a very simple API for accepting uploads. You can use SimpleDB or your SQL database to track the URLs and permissions. Set the entire S3 bucket to private, and authenticate to it using your AWS key on the ASP.NET server.
Very little code is required to upload to S3, and very little more would be required to perform bookeeping in SQL.
Once they're in S3, grab the image resizer library and the S3 Reader plugin and you can have your entire system running in under an hour. And - it will scale properly. No disk or database space limits. Ever.
You can implement authorization using the AuthorizeImage event of the Image Resizer library. Just throw an AccessDeniedException if access isn't allowed for the current user.
If you want to tune performance a bit mare, add both the DiskCache and CloudFront plugins. CloudFront can edge-cache the public images (inexpensively), and DiskCache will handle the private images, serving them at static-file speeds.

Related

read wordpress user data into a local ms access database

I'm a MS Access developer who has a client with a wordpress website. I need a way of reading any new users who are added into the wordpress site into a microsoft access database that resides on the users local machine.
I only need to add any new records and don't need to write anything back to the site.
What would be the easiest way of doing something like this? I would sooner do it from the Access side as I'm not very familiar with wordpress, also I would prefer it to be automated so the user doesn't have to manually export from wordpress then import the data every time.
Any advice appreciated.
Thanks
Justin
There's no way to have WordPress connect to an Access DB because Access isn't persistent, it's on demand. The only way I can imagine handling it would depend on Access more than anything. Assuming Access can using the ODBC connectors installed on the windows system it's running on, you could do the following:
Setup the MySQL ODBC Connector on any systems which would run the Access DB you're setting up. I assume the WordPress install is using MySQL.
Setup a new ODBC connection using that connector within Access to the Wordpress
database (you can use the same connection information stored in the
WordPress root directory in a file called wp_config.php).
If you're connecting successfully, you can then read the wp_users table using properly formatted SQL commands (select * from wp_users, for instance).
The function within Access that manages this can either be scheduled to do it periodically while Access is open or just when Access is initialized. Depending on your needs.
You'll have to compare it to a local table of users to find differences if you're interested in all changes, though the user_login is static through normal channels so it's a good key. There's also a "user_registered" date/time column in wp_users so you could just look for users who registered since your last update/change to the local access table.
I'm not familiar with Access beyond a cursory understanding of it as a data source and some minor development functions, so there may be a much easier way to do it, but this is how I'd do it in any system that needed the user information from Wordpress.
Because Wordpress and Ms-Access live in very different environments, a trick is needed to "marry" the two. Another way we can use:
Use IIS as a webserver, so as not to collide with the port used by wordpress, so don't use port 80. Just use any port.
Use ASP to access Access Database (of course there is a block of ASP code to activate the connector to the Access file, then create a recordset via that connector for record2 and display it to the browser). Call it with the file name: recordshower.asp
The recordshower.asp file must be able to be called by the browser.
After that, go back to a page in wordpress, insert <iframe src=recordshower.asp width:.... ></iframe>
So, a wordpress page can display the contents of an Access table, with the help of ASP
I export the WordPress entries to a .CSV, I then run an Excel macro, which is stored in my personal workbook, to open the file from my downloads directory, convert the .CSV to .XLS, and write it to an XLS file in a known location. I then push a button in my MS Access program to read the entries from the .XLS file (which is externally linked to my MS Access as a Excel spreadsheet) and update my MS Access tables with the data.

Saving images from a website and accessing it from another website

I have created a website let's name it a.com. Now in this website (a.com) the users can upload an image that gets saved to a folder on remote server and the path is getting saved to database.
There is a second website (b.com) which has been hosted on the same server where the image needs to be retrieved.
Can we do this? If yes then please suggest some solution
Language Used = Asp.net 4.0 C#
Backend = SQL2008
It cane be done, if both website can access the remote folder. You need to use something like System.Net.WebClient to download image from remote server.
Since your using SQL and .Net im going to assume your using IIS aswell,
Creating a Virtual directory is probably your best bet, Easy to setup, easy to manage and Extremely handy to understand (if not vital)
http://www.iis.net/learn/get-started/planning-your-iis-architecture/understanding-sites-applications-and-virtual-directories-on-iis
This is assuming you want to display the image in b.com, if you simply want to retrieve it you can do so by retrieving the path and using the image in any other way, you may need to set permissions on the image folder.
first of all both sites should use the same database to share information about images.
If I understand correctly b.com and the files are on the same server. If so put folder's virtual path to configuration.
After that, check database for new records. If found one, parse the name of the file and find it on the server.
As an example you get an image on a.com and insert it on database as
name="image.jpg"
b.com checks database for new records and finds image.jpg.
b.com reads configuration and finds
path="http://c.com/"
combines path and imagename
fulllink="http://c.com/image.jpg"

Where to store images for albums?

I am creating a module of my website where I can display images in "albums", much like facebook.
For storing/grouping images, I planned on having them in the ~/Images folder inside my application's structure. Is this considered bad practice, or will it open up my application to any security vulnerabilities? I read that you shouldn't place things like this in your site structure, but I don't quite understand why (or if this is the same scenario).
Therefore, albums would be grouped as...
~/Images/album1, ~/Images/album2, etc.
Is this an appropriate thing to put inside App_Data, or is there a more 'preferred' location for things such as this?
Sorry if this is a trivial question.
All three of the answers here are good. There is no preferred storage for uploaded images, it's all up to you based on your requirements.
As Henhealg says, don't store them in App_Data. If you put them here, they will not be accessible from the web. For example, the following would not render an image even if the path was correct:
<img src="/App_Data/album1/image1.png" alt="" />
One option is to have your local ~/Albums directory mapped to a different folder accessible to the web server, like sylon says. This keeps the images out of the directory where your MVC app is served from, but "pretends" that they are there. If you control IIS and can set up a file share, this may be an option for you.
Also, like XToro says, storing them in a SQL database is an option. Storing here is flexible because you don't have to worry about folder or file name collisions. Multiple users can each have albums and files with the same names, yet they won't collide because they don't occupy filesystem space the same way normal files do. If security is important to your app (not showing photos or albums to unauthorized users), having them in a SQL table makes this fairly easy.
However if you are not as worried about security or file naming collisions, you can just as easily store them in your MVC app's ~/Images or ~/Albums directory.
Depending on the performance of your server, you may want to consider storing your images into a database using BLOB
https://dev.mysql.com/doc/refman/5.0/en/blob.html
Images can be easily sorted, organized, categorized without the need to worry about folder structures and folder permissions. Simply use your PHP/AJAX/language of your choice to provide the authentication and choose which files you wish to display.
This way, each image can have it's own fields (as many as you want) like the user who posted it, the original filename, a caption, the album it belongs in etc etc
Since you can easily as a user check where the images are stored once the application is in production, where you store the images does not matter as much as what permissions you set to the folder(s) that the images are stored in.
I would use file system as you are saying but store it outside of the application folder as you are saying it is bad practice. I agree with this - when i do deployments I prefer to delete everything and drop in the new code and keep the web.config file that way I always have a clean environment and it is much easier to get started from scratch without having to worry about what I need to back up or bring from previous install.
I would use IIS to map the directory into my solution wherever I desire from a network share storage or whereever you want to safely keep your albums.
e.g. D:\MySafeStorage\Albums\ map to your website's ~\Albums\ when your website is in C:\inetpub\MyWebSite\

IIS Security: Why is it dangerous to make locally hosted xml files writable by the application pool account?

I have a website that reads an xml file, caches the file's object model, and i have web pages that read from the cache. I now want to make that xml file writable by the application pool account that runs the website so it can be managed by the website.
I've heard from peers that making that file writable is a security risk because if a hacker were to hack the website, he could potentially use the app pool account to overwrite that xml file and put whatever he/she wants into that file. However, since that file is read by directly hitting the web cache (and not the xml file) and the application pool account has write access to it, doesn't that mean a hacker can modify the object model that represent the xml file, regardless if the xml file is writable? By modifying the web cache, the hacker could inflict the same damage as if he had access to the web cache. I don't see how making the xml file read-only makes the website safer from hackers.
If I understand correctly, your xml file is read, turned into an object or a collection or some .NET data structure. And presumably only xml files of a certain schema can be successfully read this way.
I guess this depends on if there is something interesting in the xml file. If the xml file is the list of administrators, then as a hypothetical hacker I'd like to modify that file and add my name to the administrators list, which will result in an xml file that still serializes and deserializes to the data structure previous defined in code.
Another way to use write ability, would be to update a price list so that the prices are all free or heavily discounted.
If the XML file is a list of US states, then even if I could modify the list, I'm not sure what I could do with it outside of mischief, which is a larger concern for internet apps than for intranet apps.
I would put the file in the App_Data folder so that it can't be downloaded directly, which will make it harder for a hacker to make correct modifications to it... but security through obscurity is not really a good plan on it's own.
If the hacker were to hack the website, then security is compromised anyway. Allowing write access to the XML on it's own shouldn't be an issue, but I wouldn't give this access to any other files within your website.

In which folder can I store user uploaded images

I've a classified ads system on ASP.NET/c#/MS SQL, and I'm trying to figure out where to store the images that people upload when placing an ad. The ad itself is being stored in a SQL server database.
The images are now being stored in a subfolder of my webapp. It seems to work fine, however I only recently discovered a big problem. Everytime a user deletes an ad, the attached images are to be deleted as well including the folder they reside in. This leads to a restart of the asp.net application. I searched internet and found that restarting the web-app is actually intended behaviour when a subfolder is being deleted.
Obviously, I need to fix this. But how to do that? Where can I store images in such a way that:
I can remove these images including the folders they are stored in?
I can acces them using a URL (the images need to be shown in the
webpages)
Without getting the web-app being
restarted?
Any feedback is appreciated!
Paul
See this question Deleting a directory results in application restart
An other alternative would be to store the images in the DB instead.
Another option would be to put the images in a directory completely unrelated to the web site then serve the images through a scripted page or handler. It would make all of your image urls look like mydomaincom/serveimage.aspx?imageid=323422, but unless you're counting on the name somewhere that really shouldn't matter much. Obviously it would require a modification to the page that serves the images in the first place as well, but if sub directories of this unrelated directory are deleted IIS really shouldn't care at all.
maybe you can store the images in SQL (check at the filestream feature in this case)
if not, I suppose you have somewhere in a business facade class, a service class or wherever you want, a methode "DeleteAd".
This method will have to do two things :
-delete the sql data
-delete the file image
also, you may change the image store to another folder, outside the web app. You will probably end with writing a custom handler (myhandler.ashx?fileid=XX) to serve the files, or a custom route and control if you use MVC.

Resources