Jedyne rozwiązanie, jakie mogę wymyślić, to użycie niestandardowego kontrolera i trasy, aby zrobić to za Ciebie. Ale to nie jest czyste rozwiązanie.
Najpierw potrzebna jest klasa PublicController z metodą akcji GetFile. Zakłada to, że wszystkie pliki znajdują się bezpośrednio w folderze public/content. Obsługa folderów sprawia, że rzeczy są bardziej skomplikowane.
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);
}
}
Teraz wystarczy trasy u dołu listy tras, które wygląda następująco:
routes.MapRoute("PublicContent", "{file}", new {controller = "Public", action = "GetFile"});
Problem polega na tym, teraz, kiedy po prostu umieścić w nazwie kontrolera jak „Home zamiast domyślnej metody akcji Index na kontrolerze HomeController zakłada się, że chcesz pobrać plik o nazwie "Home" z katalogu zawartości. Tak więc, powyżej trasy pliku, musisz dodać trasę dla każdego kontrolera, aby wiedział, jak uzyskać działanie Index.
routes.MapRoute("HomeIndex", "Home", new { controller = "Home", action = "Index" });
Więc jeden sposób wokół to zmienić trasę tak:
routes.MapRoute("PublicContent", "{file}.{extension}", new {controller = "Public", action = "GetFile"});
i sposobu działania w tym:
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);
}
Tak jak mówiłem, to zakłada się, że wszystkie pliki znajdują się w katalogu zawartości, a nie w podfolderach. Ale jeśli chcesz zrobić podfoldery jak Treści/css/site.css można dodać swoje trasy tak:
routes.MapRoute("PublicContent_sub", "{subfolder}/{file}.{extension}", new { controller = "Public", action = "GetFileInFolder" });
routes.MapRoute("PublicContent", "{file}.{extension}", new { controller = "Public", action = "GetFile"});
Teraz metoda działania musi się zmienić też.
Jeśli zaczniesz umieszczać wiele poziomów w strukturze folderów, stanie się to coraz brzydsze i brzydsze. Ale może to zadziała dla ciebie. Jestem pewien, że liczyłeś na pole wyboru we właściwościach projektu, ale jeśli istnieje, nie wiem o tym.
To dobry pomysł. Bardzo mądre myślenie. – NerdFury
Wydaje się, że jest to najskuteczniejszy sposób na wykonanie tego zadania, zarówno pod względem wysiłku, jak i wydajności. Spróbuję tego. Dzięki! – AlbertVo