Die einzige Lösung, die mir einfällt, ist die Verwendung eines benutzerdefinierten Controllers und einer Route, die dies für Sie erledigen. Aber es ist nicht eine saubere Lösung.
Zunächst benötigen Sie eine PublicController-Klasse mit einer GetFile-Aktionsmethode. Dabei wird davon ausgegangen, dass sich alle Dateien direkt im Ordner public/content befinden. Die Handhabung von Ordnern macht die Sache komplizierter.
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);
}
}
Jetzt brauchen Sie nur noch eine Route, die am Ende Ihrer Routenliste steht und wie folgt aussieht:
routes.MapRoute("PublicContent", "{file}", new {controller = "Public", action = "GetFile"});
Das Problem ist jetzt, wenn Sie nur in einem Controller-Namen wie "Home" statt standardmäßig auf die Index-Action-Methode auf der HomeController, es nimmt an, Sie wollen eine Datei namens "Home" aus dem Content-Verzeichnis herunterladen. Also, über die Datei-Route, müssten Sie eine Route für jeden Controller hinzufügen, so dass es weiß, um die Index-Aktion stattdessen zu erhalten.
routes.MapRoute("HomeIndex", "Home", new { controller = "Home", action = "Index" });
Eine Möglichkeit, dies zu umgehen, besteht darin, die Route folgendermaßen zu ändern:
routes.MapRoute("PublicContent", "{file}.{extension}", new {controller = "Public", action = "GetFile"});
Und die Aktionsmethode dazu:
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);
}
Wie ich schon sagte, setzt dies voraus, dass sich alle Dateien im Inhaltsverzeichnis und nicht in Unterordnern befinden. Wenn Sie jedoch Unterordner wie Content/css/site.css verwenden möchten, können Sie Ihre Routen wie folgt hinzufügen:
routes.MapRoute("PublicContent_sub", "{subfolder}/{file}.{extension}", new { controller = "Public", action = "GetFileInFolder" });
routes.MapRoute("PublicContent", "{file}.{extension}", new { controller = "Public", action = "GetFile"});
Nun muss auch die Aktionsmethode geändert werden.
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);
}
Wenn Sie mehrere Ebenen in der Ordnerstruktur erreichen, wird dies immer unschöner. Aber vielleicht klappt es bei Ihnen ja so. Ich bin sicher, dass Sie auf ein Kontrollkästchen in den Projekteigenschaften gehofft haben, aber wenn es eines gibt, weiß ich es nicht.