'Serving static file on ASP.NET MVC (C#)

I am completely new to .NET framework and i would like to know what is the best way to serve static content and to access user generated content.

Suppose i have the following files:

logo.jpg
document.pdf
etc.doc

Where should i put this (on which folders) ? And how do i access it?

Lastly, taking it into another level. Suppose i have a web apps that allows user to upload a document (let say some pics). What i would like to know is how should the structure of my folder/directory look like?

normaly in django / CI i would have a folder as follows:

application/{all-web-app-related-folder-and-file-goes-here} uploads/{all-related-user-generated-content-goes-here-categorized-by-file-type} assets/{css-javascript-document-would-go-here}

note: i haven't done anything or made any attempt to it. Simply because i have no idea how to access try static content. I once tried to access the *.css or *.js files located inside Content/Scripts folder.

i.e: localhost:12345/Scripts/jquery.js

It turns out, it is not a straightforward process in ASP.NET MVC

Oh by the way, in certain occasion, i would also like to access my images from my css file instead. Which raises yet another confusion to me.

EDIT 1: I read the following article

http://www.c-sharpcorner.com/uploadfile/dhananjaycoder/working-with-images-in-Asp-Net-mvc-framework/

however it is not applicable to my current version of MVC (i am using MVC 5)

EDIT 2: So, this is what i have been experimenting so far

  1. I created a folder called Assets on the root directory (same level as Models, Controllers, etc).
  2. Inside Asset i create sub-folders (i.e. images, documents, etc)
  3. Then i want to access those file directly from my views i would go like this:

    img src="@Url.Content("~/Asset/images/picture.png")"

The above example is appropriate if i want to access image file.

I however not sure if this is the ideal way to do it. It is however, the simplest solution i can come across at the moment (or should i say, rather naive).

Any hints would be appreciated.



Solution 1:[1]

Suppose I have the following files: logo.jpg, document.pdf, etc.doc, where should I put this (on which folders) ? And how do i access it?

What you had on EDIT 2 is completely fine. The MVC framework is smart enough to disable dictionary browsing. If you're trying to asset /assets/ or /assets/images, you will get a 403.

Moreover, even you have a controller named "assets", a method called "images", and a string id "picture.png", the request won't hit the controller method. Instead, it will still serve you the image file. It looks like MVC takes the precedence of the static files it finds over the MVC routings?


Suppose I have a web apps that allows user to upload a document (let's say some pics). What I would like to know is how should the structure of my folder/directory look like?

If you're planning to just store user's uploads as physical files in the application (rather than saving them to a persistence store), you can create a folder like "uploads" on the root and put their uploads there.

I would separate their uploads by their IDs (hopefully it's a GUID rather than just integer IDs) into different sub folders under "uploads" just in case when you want to display the upload path on the front end, the user cannot easily guess where other users' uploads are:

// assets
// uploads
//     xxxx-xxxx-xxxx-xxxx
//         files
//     xxxx-xxxx-xxxx-xxxx
//         files

Don't forget to set this uploads folder's permission on the server you publish the app to.


In certain occasion, I would also like to access my images from my css file instead.

In this case, you will have to use relative URLs, and MVC defaults its root to ~/Content. For example, let's say you want to use picture.png you saved under /assets/images/ as the background picture of a block:

#test-block {
    width: 250px;
    height: 250px;
    background-image: url(`~/assets/images/picture.png`);'
    background-size: cover;
}

You think it would access the picture correctly and use it as the background of the block. But in fact, it would generate something like this:

background-image: localhost/content/~/assets/images/picture.png

This is a bummer because you will have to manually go back up 1 level to grab the image, using ../ instead of ~/:

background-image: url(`../assets/images/picture.png`);'

To me, this is not an accepted solution, and it would be so buggy if you publish the app to a virtual folder on the server, which is not the wwwroot.

For setting background images like this, I would prefer to use inline styles with the help of @Url.Content() because I don't need to worry about how their paths are related to each other:

<div id="test-block" 
    style="background-image: url('@Url.Content("~/assets/images/picture.png")');">
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 David Liang