La única solución que se me ocurre es utilizar un controlador personalizado y una ruta para hacer esto por usted. Pero no es una solución limpia.
Primero necesita una clase PublicController con un método de acción GetFile. Esto supone que todos los archivos están en la carpeta pública/de contenido directamente. Manejar carpetas hace las cosas más complicadas.
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);
}
}
Ahora, sólo tendrá una ruta cerca de la parte inferior de la lista de rutas que tiene este aspecto:
routes.MapRoute("PublicContent", "{file}", new {controller = "Public", action = "GetFile"});
El problema es, ahora, cuando usted acaba de poner en un nombre de controlador como 'Home 'en lugar de utilizar el método de acción Índice en el HomeController, supone que desea descargar un archivo llamado "Inicio" desde el directorio de contenido. Por lo tanto, por encima de la ruta del archivo, deberá agregar una ruta para cada controlador, de modo que sepa para obtener la acción Índice.
routes.MapRoute("HomeIndex", "Home", new { controller = "Home", action = "Index" });
lo tanto, una forma de evitar eso es cambiar la ruta a:
routes.MapRoute("PublicContent", "{file}.{extension}", new {controller = "Public", action = "GetFile"});
Y el método de acción a esto:
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);
}
Como dije, esto supone que todos los archivos están en el directorio de contenido y no en subcarpetas. Pero si lo que quería hacer subcarpetas como contenido/css/site.css se podría añadir sus rutas como esta:
routes.MapRoute("PublicContent_sub", "{subfolder}/{file}.{extension}", new { controller = "Public", action = "GetFileInFolder" });
routes.MapRoute("PublicContent", "{file}.{extension}", new { controller = "Public", action = "GetFile"});
Ahora el método de acción tiene que cambiar también.
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);
}
Si comienza a obtener varios niveles de profundidad en la estructura de carpetas, esto se vuelve más feo y feo. Pero tal vez esto funcione para ti. Estoy seguro de que estabas esperando una casilla de verificación en las propiedades del proyecto, pero si hay una, no lo sé.
Esa es una buena idea. Pensamiento muy inteligente. – NerdFury
Esta parece ser la forma más eficiente de hacerlo tanto en esfuerzo como en rendimiento. Voy a intentar esto. ¡Gracias! – AlbertVo