The only solution I can think of, is to use a custom controller and route to do this for you. But it isn't a clean solution.
First you need a PublicController class with a GetFile action method. This assumes that all files are in the public/content folder directly. Handling folders makes things more complicated.
public class PublicController : Controller
{
private IDictionary<String, String> mimeTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{{"css", "text/css"}, {"jpg", "image/jpg"}};
public ActionResult GetFile(string file)
{
var path = Path.Combine(Server.MapPath("~/Content"), file);
if (!System.IO.File.Exists(path)) throw new HttpException(404, "File Not Found");
var extension = GetExtension(file); // psuedocode
var mimetype = mimeTypes.ContainsKey(extension) ? mimeTypes[extension] : "text/plain";
return File(path, mimetype);
}
}
Now, you just need a route near the bottom of your list of routes that looks like this:
routes.MapRoute("PublicContent", "{file}", new {controller = "Public", action = "GetFile"});
The problem is, now when you just put in a controller name like 'Home' instead of defaulting to the Index action method on the HomeController, it assumes you want to download a file called "Home" from the content directory. So, above the file route, you would need to add a route for each controller so it knows to get the Index action instead.
routes.MapRoute("HomeIndex", "Home", new { controller = "Home", action = "Index" });
So, one way around that is to change the route to this:
routes.MapRoute("PublicContent", "{file}.{extension}", new {controller = "Public", action = "GetFile"});
And the action method to this:
public ActionResult GetFile(string file, string extension)
{
var path = Path.Combine(Server.MapPath("~/Content"), file + "." + extension);
if (!System.IO.File.Exists(path)) throw new HttpException(404, "File Not Found");
var mimetype = mimeTypes.ContainsKey(extension) ? mimeTypes[extension] : "text/plain";
return File(path, mimetype);
}
Like I said, this assumes that all files are in the content directory, and not in subfolders. But if you wanted to do subfolders like Content/css/site.css you could add your routes like this:
routes.MapRoute("PublicContent_sub", "{subfolder}/{file}.{extension}", new { controller = "Public", action = "GetFileInFolder" });
routes.MapRoute("PublicContent", "{file}.{extension}", new { controller = "Public", action = "GetFile"});
Now the action method has to change too.
public ActionResult GetFile(string file, string extension)
{
return GetFileInFolder("", file, extension);
}
public ActionResult GetFileInFolder(string subfolder, string file, string extension)
{
var path = Path.Combine(Server.MapPath("~/Content"), subfolder, file + "." + extension);
if (!System.IO.File.Exists(path)) throw new HttpException(404, "File Not Found");
var mimetype = mimeTypes.ContainsKey(extension) ? mimeTypes[extension] : "text/plain";
return File(path, mimetype);
}
If you start getting multiple levels deep in the folder structure, this gets uglier and uglier. But maybe this will work for you. I'm sure you were hoping for a checkbox in the project properties, but if there is one, I don't know about it.