Eventos
Campeonato mundial de DataViz de Power BI
14 feb, 16 - 31 mar, 16
Con 4 posibilidades de entrar, podrías ganar un paquete de conferencia y convertirlo en el Live Grand Finale en Las Vegas
Saber másEste explorador ya no se admite.
Actualice a Microsoft Edge para aprovechar las características y actualizaciones de seguridad más recientes, y disponer de soporte técnico.
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la directiva de compatibilidad de .NET y .NET Core. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión de .NET 9 de este artículo.
Por Rick Anderson
Los archivos estáticos, como HTML, CSS, imágenes y JavaScript, son activos que una aplicación de ASP.NET Core proporciona directamente a los clientes de forma predeterminada.
Para obtener una guía sobre archivos estáticos de Blazor, que se agregue o reemplace la guía de este artículo, consulta Archivos estáticos de Blazor en ASP.NET Core.
Los archivos estáticos se almacenan en el directorio raíz web del proyecto. El directorio predeterminado es {content root}/wwwroot
, pero se puede cambiar con el método UseWebRoot. Para obtener más información, consulta Raíz del contenido y Raíz web.
El método CreateBuilder establece la raíz de contenido en el directorio actual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Se puede acceder a los archivos estáticos a través de una ruta de acceso relativa a la raíz web. Por ejemplo, las plantillas de proyecto Aplicación web contienen varias carpetas dentro de la carpeta wwwroot
:
wwwroot
css
js
lib
Considera la posibilidad de usar una aplicación con el archivo wwwroot/images/MyImage.jpg
. El formato del URI para acceder a un archivo en la carpeta images
es https://<hostname>/images/<image_file_name>
. Por ejemplo: https://localhost:5001/images/MyImage.jpg
La creación de aplicaciones web de rendimiento requiere la optimización de la entrega de recursos al explorador. Entre las posibles optimizaciones se incluyen:
UseStaticFiles
también proporciona archivos estáticos, pero no proporciona el mismo nivel de optimización que MapStaticAssets
. Para obtener una comparación de UseStaticFiles
y MapStaticAssets
, consulta Optimización de la entrega de recursos web estáticos .
Las plantillas de aplicación web predeterminadas llaman al método MapStaticAssets en Program.cs
, que permite proporcionar archivos estáticos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
La sobrecarga del método UseStaticFiles
sin parámetros marca los archivos en la raíz web como que se pueden proporcionar. El siguiente marcado hace referencia a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
En el marcado anterior, el carácter de tilde de la ñ ~
apunta a la raíz web.
Considere una jerarquía de directorios en la que residen fuera de la raíz web los archivos estáticos que se van a proporcionar:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una solicitud puede acceder al archivo red-rose.jpg
configurando el middleware de archivos estáticos como se muestra a continuación:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); //Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
En el código anterior, la jerarquía del directorio MyStaticFiles se expone públicamente a través del segmento de URI StaticFiles. Una solicitud a https://<hostname>/StaticFiles/images/red-rose.jpg
sirve al archivo red-rose.jpg
.
El siguiente marcado hace referencia a MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para entregar archivos desde varias ubicaciones, vea Entrega de archivos desde varias ubicaciones.
Se puede usar un objeto StaticFileOptions para establecer encabezados de respuesta HTTP. Además de configurar el servicio de archivos estáticos desde la raíz web, el código siguiente establece el encabezado Cache-Control:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
El código anterior hace que los archivos estáticos estén disponibles públicamente en la memoria caché local durante una semana.
Las plantillas de ASP.NET Core llaman a MapStaticAssets antes de llamar a UseAuthorization. La mayoría de las aplicaciones siguen este patrón. Cuando se llama al middleware de archivos estáticos antes de al middleware de autorización:
wwwroot
, son accesibles públicamente.Para proporcionar archivos estáticos según su autorización:
wwwroot
.UseStaticFiles
, especificando una ruta de acceso, después de llamar a UseAuthorization
.using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
En el código anterior, la directiva de autorización de reserva requiere que se autentiquen todos los usuarios. Los puntos de conexión como los controladores, Razor Pages, etc. que especifican sus propios requisitos de autorización no usan la directiva de autorización de reserva. Por ejemplo, Razor Pages, controladores o métodos de acción con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usan el atributo de autorización aplicado en lugar de la directiva de autorización de reserva.
RequireAuthenticatedUser agrega DenyAnonymousAuthorizationRequirement a la instancia actual, lo que exige que el usuario actual se autentique.
Los recursos estáticos en wwwroot
son accesibles públicamente porque se llama al middleware de archivos estáticos predeterminado (app.UseStaticFiles();
) antes de a UseAuthentication
. Los recursos estáticos de la carpeta MyStaticFiles requieren autenticación. En el código de ejemplo se muestra esto.
Un enfoque alternativo a proporcionar archivos según la autorización es:
Almacénalos fuera de wwwroot
y cualquier directorio al que el middleware de archivos estáticos tenga acceso.
Proporciónalos a través de un método de acción al que se aplica la autorización y devuelva un objeto FileResult:
[Authorize]
public class BannerImageModel : PageModel
{
private readonly IWebHostEnvironment _env;
public BannerImageModel(IWebHostEnvironment env) =>
_env = env;
public PhysicalFileResult OnGet()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
}
El enfoque anterior requiere una página o un punto de conexión por archivo. El código siguiente devuelve archivos o carga archivos para usuarios autenticados:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
app.MapPost("/files",
async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be
// manipulated by the end-user. See the `Utilities.IsFileValid` method that
// takes an IFormFile and validates its signature within the
// AllowedFileSignatures
var fileSaveName = Guid.NewGuid().ToString("N")
+ Path.GetExtension(file.FileName);
await SaveFileWithCustomFileName(file, fileSaveName);
context.Response.Headers.Append("Location",
linker.GetPathByName(context, "GetFileByName",
new { fileName = fileSaveName}));
return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");
app.Run();
IFormFile en el ejemplo anterior usa el búfer de memoria para la carga. Para controlar el streaming de uso de archivos de gran tamaño. Consulta Carga de archivos de gran tamaño con streaming.
Consulta la carpeta StaticFileAuth de GitHub para obtener el ejemplo completo.
El examen de directorios permite enumerar directorios dentro de los directorios especificados.
Por motivos de seguridad, el examen de directorios está deshabilitado de forma predeterminada. Para obtener más información, consulta Consideraciones de seguridad para archivos estáticos.
Habilita el examen de directorios con AddDirectoryBrowser y UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
El código anterior permite el examen de directorios de la carpeta wwwroot/images usando la dirección URL https://<hostname>/MyImages
, con vínculos a cada archivo y carpeta:
AddDirectoryBrowser
agrega servicios requeridos por el middleware de examen de directorios, incluido HtmlEncoder. Estos servicios se pueden agregar mediante otras llamadas, como AddRazorPages, pero se recomienda llamar a AddDirectoryBrowser
para asegurarse de que los servicios se agregan en todas las aplicaciones.
El establecimiento de una página predeterminada proporciona a los visitantes un punto inicial en un sitio. Para servir un archivo predeterminado desde wwwroot
sin necesidad de que la dirección URL de la solicitud incluya el nombre del archivo, llame al método UseDefaultFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Debe llamarse a UseDefaultFiles
antes de a UseStaticFiles
para proporcionar el archivo predeterminado. UseDefaultFiles
es un sistema de reescritura de direcciones URL que no proporciona el archivo.
Con UseDefaultFiles
, las solicitudes a una carpeta en wwwroot
buscan:
default.htm
default.html
index.htm
index.html
El primer archivo que se encuentra en la lista se sirve como si la solicitud incluyera el nombre de archivo. La dirección URL del explorador sigue reflejando el URI solicitado. Por ejemplo, en la aplicación de ejemplo, una solicitud para https://localhost:<port>/def/
atiende default.html
desde wwwroot/def
.
El código siguiente cambia el nombre de archivo predeterminado a mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseFileServer combina la funcionalidad de UseStaticFiles
y UseDefaultFiles
y, opcionalmente, la de UseDirectoryBrowser
.
Llama a app.UseFileServer
para poder proporcionar archivos estáticos y el archivo predeterminado. El examen de directorios no está habilitado:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Ten en cuenta la siguiente jerarquía de directorios:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios de MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Se debe llamar a AddDirectoryBrowser cuando el valor de la propiedad EnableDirectoryBrowsing
es true
.
Al usar la jerarquía de archivos y el código anteriores, las direcciones URL se resuelven como se indica a continuación:
Identificador URI | Respuesta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
lista de directorios |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Si no existe ningún archivo con el nombre predeterminado en el directorio MyStaticFiles, https://<hostname>/StaticFiles
devuelve la lista de directorios con vínculos activos:
UseDefaultFiles y UseDirectoryBrowser realizan un redireccionamiento del lado cliente desde el URI de destino sin una /
final hasta el URI de destino una /
final. Por ejemplo, desde https://<hostname>/StaticFiles
hasta https://<hostname>/StaticFiles/
. Las direcciones URL relativas dentro del directorio StaticFiles no son válidas sin una barra diagonal final (/
), a menos que se use la opción RedirectToAppendTrailingSlash de DefaultFilesOptions.
La clase FileExtensionContentTypeProvider contiene una propiedad Mappings que actúa como una asignación de extensiones de archivo para tipos de contenido MIME. En el ejemplo siguiente, se asignan varias extensiones de archivo a los tipos MIME conocidos. Se reemplaza la extensión .rtf y se quita .mp4:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Consulta Tipos de contenido MIME.
El middleware de archivos estáticos entiende casi 400 tipos de contenido de archivo conocidos. Si el usuario solicita un archivo con un tipo de archivo desconocido, el middleware de archivos estáticos pasa la solicitud al siguiente middleware de la canalización. Si ningún middleware se ocupa de la solicitud, se devuelve una respuesta 404 No encontrado. Si se habilita la exploración de directorios, se muestra un vínculo al archivo en una lista de directorios.
El código siguiente permite proporcionar tipos desconocidos y procesa el archivo desconocido como una imagen:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Con el código anterior, una solicitud para un archivo con un tipo de contenido desconocido se devuelve como una imagen.
Advertencia
Habilitar ServeUnknownFileTypes supone un riesgo para la seguridad. Está deshabilitado de forma predeterminada y no se recomienda su uso. FileExtensionContentTypeProvider proporciona una alternativa más segura a ofrecer archivos con extensiones no estándar.
Tenga en cuenta la página Razor siguiente que muestra el archivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
y UseFileServer
tienen como valor predeterminado el proveedor de archivos que apunta a wwwroot
. Se pueden proporcionar instancias adicionales de UseStaticFiles
y UseFileServer
con otros proveedores de archivos para proporcionar archivos desde otras ubicaciones. En el ejemplo siguiente se llama a UseStaticFiles
dos veces para entregar archivos desde wwwroot
y MyStaticFiles
:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Con el código anterior:
/MyStaticFiles/image3.png
.WebRootFileProvider
no se ha actualizado para incluir la carpeta MyStaticFiles
.El código siguiente actualiza WebRootFileProvider
, que permite al asistente de etiquetas de imagen proporcionar una versión:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.MapStaticAssets();
Nota
El enfoque anterior se aplica a las aplicaciones de Razor Pages y MVC. Para obtener guías que se aplican a Blazor Web App, consulta Archivos estáticos Blazor de ASP.NET Core.
Advertencia
UseDirectoryBrowser
y UseStaticFiles
pueden producir pérdidas de información confidencial. Se recomienda deshabilitar el examen de directorios en producción. Revisa cuidadosamente los directorios que se habilitan mediante UseStaticFiles
o UseDirectoryBrowser
. Todo el directorio y sus subdirectorios pasan a ser accesibles públicamente. Almacena los archivos adecuados para proporcionarlos al público en un directorio dedicado, como <content_root>/wwwroot
. Separa estos archivos de las vistas MVC, de Razor Pages, de los archivos de configuración, etc.
Las direcciones URL para el contenido que se expone a través de UseDirectoryBrowser
, UseStaticFiles
y MapStaticAssets
están sujetas a la distinción entre mayúsculas y minúsculas, y a restricciones de caracteres del sistema de archivos subyacente. Por ejemplo, Windows no distingue entre mayúsculas y minúsculas, pero macOS y Linux sí.
Las aplicaciones de ASP.NET Core hospedadas en IIS usan el módulo de ASP.NET Core para reenviar todas las solicitudes a la aplicación, incluidas las solicitudes de archivos estáticos. No se utiliza el controlador de archivos estáticos de IIS y no tiene la posibilidad de controlar las solicitudes.
Completa los pasos siguientes en el Administrador de IIS para quitar el controlador de archivos estáticos de IIS en el nivel de servidor o de sitio web:
Advertencia
Si el controlador de archivos estáticos de IIS está habilitado y el módulo de ASP.NET Core no está configurado correctamente, se proporcionan archivos estáticos. Esto sucede, por ejemplo, si el archivo web.config no está implementado.
.cs
y .cshtml
) fuera de la raíz web del proyecto de la aplicación. Por lo tanto, se crea una separación lógica entre el contenido del lado cliente de la aplicación y el código basado en servidor. Esto impide que se filtre el código del lado servidor.Cuando IWebHostEnvironment.WebRootPath se establece en una carpeta distinta de wwwroot
:
wwwroot
y en la propiedad IWebHostEnvironment.WebRootPath
actualizada se proporcionan desde wwwroot
.IWebHostEnvironment.WebRootPath
actualizada.Considera una aplicación web creada con la plantilla web vacía:
Que contenga un archivo Index.html
en wwwroot
y wwwroot-custom
.
Con el siguiente archivo Program.cs
actualizado que establece WebRootPath = "wwwroot-custom"
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Look for static files in "wwwroot-custom"
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();
En el código anterior, las solicitudes a /
:
wwwroot/Index.html
wwwroot-custom/Index.html
Para asegurarte de que se devuelven los recursos de wwwroot-custom
, usa uno de los enfoques siguientes:
Elimina los recursos con nombre duplicado en wwwroot
.
Establece "ASPNETCORE_ENVIRONMENT"
de Properties/launchSettings.json
en cualquier valor distinto de "Development"
.
Deshabilita completamente los recursos web estáticos estableciendo <StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
en el archivo del proyecto. ADVERTENCIA, al deshabilitar los recursos web estáticos, se deshabilitan las bibliotecas de clases de Razor.
Agrega el siguiente XML al archivo del proyecto:
<ItemGroup>
<Content Remove="wwwroot\**" />
</ItemGroup>
El código siguiente actualiza IWebHostEnvironment.WebRootPath
a un valor que no es de desarrollo, lo que garantiza que se devuelva contenido duplicado de wwwroot-custom
en lugar de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();
Por Rick Anderson
Los archivos estáticos, como HTML, CSS, imágenes y JavaScript, son activos que una aplicación de ASP.NET Core proporciona directamente a los clientes de forma predeterminada.
Los archivos estáticos se almacenan en el directorio raíz web del proyecto. El directorio predeterminado es {content root}/wwwroot
, pero se puede cambiar con el método UseWebRoot. Para obtener más información, consulta Raíz del contenido y Raíz web.
El método CreateBuilder establece la raíz de contenido en el directorio actual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Se puede acceder a los archivos estáticos a través de una ruta de acceso relativa a la raíz web. Por ejemplo, las plantillas de proyecto Aplicación web contienen varias carpetas dentro de la carpeta wwwroot
:
wwwroot
css
js
lib
Considere la posibilidad de crear la carpeta wwwroot/images y agregar el archivo wwwroot/images/MyImage.jpg
. El formato del URI para acceder a un archivo en la carpeta images
es https://<hostname>/images/<image_file_name>
. Por ejemplo: https://localhost:5001/images/MyImage.jpg
Las plantillas de aplicación web predeterminadas llaman al método UseStaticFiles en Program.cs
, que permite proporcionar archivos estáticos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
La sobrecarga del método UseStaticFiles
sin parámetros marca los archivos en la raíz web como que se pueden proporcionar. El siguiente marcado hace referencia a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
En el marcado anterior, el carácter de tilde de la ñ ~
apunta a la raíz web.
Considere una jerarquía de directorios en la que residen fuera de la raíz web los archivos estáticos que se van a proporcionar:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una solicitud puede acceder al archivo red-rose.jpg
configurando el middleware de archivos estáticos como se muestra a continuación:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
En el código anterior, la jerarquía del directorio MyStaticFiles se expone públicamente a través del segmento de URI StaticFiles. Una solicitud a https://<hostname>/StaticFiles/images/red-rose.jpg
sirve al archivo red-rose.jpg
.
El siguiente marcado hace referencia a MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para entregar archivos desde varias ubicaciones, vea Entrega de archivos desde varias ubicaciones.
Se puede usar un objeto StaticFileOptions para establecer encabezados de respuesta HTTP. Además de configurar el servicio de archivos estáticos desde la raíz web, el código siguiente establece el encabezado Cache-Control:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
El código anterior hace que los archivos estáticos estén disponibles públicamente en la memoria caché local durante una semana (604800 segundos).
Las plantillas de ASP.NET Core llaman a UseStaticFiles antes de llamar a UseAuthorization. La mayoría de las aplicaciones siguen este patrón. Cuando se llama al middleware de archivos estáticos antes de al middleware de autorización:
wwwroot
, son accesibles públicamente.Para proporcionar archivos estáticos según su autorización:
wwwroot
.UseStaticFiles
, especificando una ruta de acceso, después de llamar a UseAuthorization
.using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
En el código anterior, la directiva de autorización de reserva requiere que se autentiquen todos los usuarios. Los puntos de conexión como los controladores, Razor Pages, etc. que especifican sus propios requisitos de autorización no usan la directiva de autorización de reserva. Por ejemplo, Razor Pages, controladores o métodos de acción con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usan el atributo de autorización aplicado en lugar de la directiva de autorización de reserva.
RequireAuthenticatedUser agrega DenyAnonymousAuthorizationRequirement a la instancia actual, lo que exige que el usuario actual se autentique.
Los recursos estáticos en wwwroot
son accesibles públicamente porque se llama al middleware de archivos estáticos predeterminado (app.UseStaticFiles();
) antes de a UseAuthentication
. Los recursos estáticos de la carpeta MyStaticFiles requieren autenticación. En el código de ejemplo se muestra esto.
Un enfoque alternativo a proporcionar archivos según la autorización es:
Almacénalos fuera de wwwroot
y cualquier directorio al que el middleware de archivos estáticos tenga acceso.
Proporciónalos a través de un método de acción al que se aplica la autorización y devuelva un objeto FileResult:
[Authorize]
public class BannerImageModel : PageModel
{
private readonly IWebHostEnvironment _env;
public BannerImageModel(IWebHostEnvironment env) =>
_env = env;
public PhysicalFileResult OnGet()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
}
El enfoque anterior requiere una página o un punto de conexión por archivo. El código siguiente devuelve archivos o carga archivos para usuarios autenticados:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
// IFormFile uses memory buffer for uploading. For handling large file use streaming instead.
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be manipulated by the end-user
// Take a look at the `Utilities.IsFileValid` method that takes an IFormFile and validates its signature within the AllowedFileSignatures
var fileSaveName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
await SaveFileWithCustomFileName(file, fileSaveName);
context.Response.Headers.Append("Location", linker.GetPathByName(context, "GetFileByName", new { fileName = fileSaveName}));
return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");
app.Run();
Consulta la carpeta StaticFileAuth de GitHub para obtener el ejemplo completo.
El examen de directorios permite enumerar directorios dentro de los directorios especificados.
Por motivos de seguridad, el examen de directorios está deshabilitado de forma predeterminada. Para obtener más información, consulta Consideraciones de seguridad para archivos estáticos.
Habilita el examen de directorios con AddDirectoryBrowser y UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
El código anterior permite el examen de directorios de la carpeta wwwroot/images usando la dirección URL https://<hostname>/MyImages
, con vínculos a cada archivo y carpeta:
AddDirectoryBrowser
agrega servicios requeridos por el middleware de examen de directorios, incluido HtmlEncoder. Estos servicios se pueden agregar mediante otras llamadas, como AddRazorPages, pero se recomienda llamar a AddDirectoryBrowser
para asegurarse de que los servicios se agregan en todas las aplicaciones.
El establecimiento de una página predeterminada proporciona a los visitantes un punto inicial en un sitio. Para servir un archivo predeterminado desde wwwroot
sin necesidad de que la dirección URL de la solicitud incluya el nombre del archivo, llame al método UseDefaultFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Debe llamarse a UseDefaultFiles
antes de a UseStaticFiles
para proporcionar el archivo predeterminado. UseDefaultFiles
es un sistema de reescritura de direcciones URL que no proporciona el archivo.
Con UseDefaultFiles
, las solicitudes a una carpeta en wwwroot
buscan:
default.htm
default.html
index.htm
index.html
El primer archivo que se encuentra en la lista se sirve como si la solicitud incluyera el nombre de archivo. La dirección URL del explorador sigue reflejando el URI solicitado.
El código siguiente cambia el nombre de archivo predeterminado a mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer combina la funcionalidad de UseStaticFiles
y UseDefaultFiles
y, opcionalmente, la de UseDirectoryBrowser
.
Llama a app.UseFileServer
para poder proporcionar archivos estáticos y el archivo predeterminado. El examen de directorios no está habilitado:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Ten en cuenta la siguiente jerarquía de directorios:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios de MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Se debe llamar a AddDirectoryBrowser cuando el valor de la propiedad EnableDirectoryBrowsing
es true
.
Al usar la jerarquía de archivos y el código anteriores, las direcciones URL se resuelven como se indica a continuación:
Identificador URI | Respuesta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Si no existe ningún archivo con el nombre predeterminado en el directorio MyStaticFiles, https://<hostname>/StaticFiles
devuelve la lista de directorios con vínculos activos:
UseDefaultFiles y UseDirectoryBrowser realizan un redireccionamiento del lado cliente desde el URI de destino sin una /
final hasta el URI de destino una /
final. Por ejemplo, desde https://<hostname>/StaticFiles
hasta https://<hostname>/StaticFiles/
. Las direcciones URL relativas dentro del directorio StaticFiles no son válidas sin una barra diagonal final (/
), a menos que se use la opción RedirectToAppendTrailingSlash de DefaultFilesOptions.
La clase FileExtensionContentTypeProvider contiene una propiedad Mappings
que actúa como una asignación de extensiones de archivo para tipos de contenido MIME. En el ejemplo siguiente, se asignan varias extensiones de archivo a los tipos MIME conocidos. Se reemplaza la extensión .rtf y se quita .mp4:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Consulta Tipos de contenido MIME.
El middleware de archivos estáticos entiende casi 400 tipos de contenido de archivo conocidos. Si el usuario solicita un archivo con un tipo de archivo desconocido, el middleware de archivos estáticos pasa la solicitud al siguiente middleware de la canalización. Si ningún middleware se ocupa de la solicitud, se devuelve una respuesta 404 No encontrado. Si se habilita la exploración de directorios, se muestra un vínculo al archivo en una lista de directorios.
El código siguiente permite proporcionar tipos desconocidos y procesa el archivo desconocido como una imagen:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Con el código anterior, una solicitud para un archivo con un tipo de contenido desconocido se devuelve como una imagen.
Advertencia
Habilitar ServeUnknownFileTypes supone un riesgo para la seguridad. Está deshabilitado de forma predeterminada y no se recomienda su uso. FileExtensionContentTypeProvider proporciona una alternativa más segura a ofrecer archivos con extensiones no estándar.
Tenga en cuenta la página Razor siguiente que muestra el archivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
y UseFileServer
tienen como valor predeterminado el proveedor de archivos que apunta a wwwroot
. Se pueden proporcionar instancias adicionales de UseStaticFiles
y UseFileServer
con otros proveedores de archivos para proporcionar archivos desde otras ubicaciones. En el ejemplo siguiente se llama a UseStaticFiles
dos veces para entregar archivos desde wwwroot
y MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Con el código anterior:
/MyStaticFiles/image3.png
.WebRootFileProvider
no se ha actualizado para incluir la carpeta MyStaticFiles
.El código siguiente actualiza WebRootFileProvider
, que permite al asistente de etiquetas de imagen proporcionar una versión:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Nota
El enfoque anterior se aplica a las aplicaciones de Razor Pages y MVC. Para obtener guías que se aplican a Blazor Web App, consulta Archivos estáticos Blazor de ASP.NET Core.
Advertencia
UseDirectoryBrowser
y UseStaticFiles
pueden producir pérdidas de información confidencial. Se recomienda deshabilitar el examen de directorios en producción. Revisa cuidadosamente los directorios que se habilitan mediante UseStaticFiles
o UseDirectoryBrowser
. Todo el directorio y sus subdirectorios pasan a ser accesibles públicamente. Almacena los archivos adecuados para proporcionarlos al público en un directorio dedicado, como <content_root>/wwwroot
. Separa estos archivos de las vistas MVC, de Razor Pages, de los archivos de configuración, etc.
Las direcciones URL para el contenido que se expone a través de UseDirectoryBrowser
y UseStaticFiles
están sujetas a la distinción entre mayúsculas y minúsculas, y a restricciones de caracteres del sistema de archivos subyacente. Por ejemplo, Windows no distingue entre mayúsculas y minúsculas, pero macOS y Linux sí.
Las aplicaciones de ASP.NET Core hospedadas en IIS usan el módulo de ASP.NET Core para reenviar todas las solicitudes a la aplicación, incluidas las solicitudes de archivos estáticos. No se utiliza el controlador de archivos estáticos de IIS y no tiene la posibilidad de controlar las solicitudes.
Completa los pasos siguientes en el Administrador de IIS para quitar el controlador de archivos estáticos de IIS en el nivel de servidor o de sitio web:
Advertencia
Si el controlador de archivos estáticos de IIS está habilitado y el módulo de ASP.NET Core no está configurado correctamente, se proporcionan archivos estáticos. Esto sucede, por ejemplo, si el archivo web.config no está implementado.
.cs
y .cshtml
) fuera de la raíz web del proyecto de la aplicación. Por lo tanto, se crea una separación lógica entre el contenido del lado cliente de la aplicación y el código basado en servidor. Esto impide que se filtre el código del lado servidor.Cuando IWebHostEnvironment.WebRootPath se establece en una carpeta distinta de wwwroot
:
wwwroot
y en la propiedad IWebHostEnvironment.WebRootPath
actualizada se proporcionan desde wwwroot
.IWebHostEnvironment.WebRootPath
actualizada.Considera una aplicación web creada con la plantilla web vacía:
Que contenga un archivo Index.html
en wwwroot
y wwwroot-custom
.
Con el siguiente archivo Program.cs
actualizado que establece WebRootPath = "wwwroot-custom"
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Look for static files in "wwwroot-custom"
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
En el código anterior, las solicitudes a /
:
wwwroot/Index.html
wwwroot-custom/Index.html
Para asegurarte de que se devuelven los recursos de wwwroot-custom
, usa uno de los enfoques siguientes:
Elimina los recursos con nombre duplicado en wwwroot
.
Establece "ASPNETCORE_ENVIRONMENT"
de Properties/launchSettings.json
en cualquier valor distinto de "Development"
.
Deshabilita completamente los recursos web estáticos estableciendo <StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
en el archivo del proyecto. ADVERTENCIA, al deshabilitar los recursos web estáticos, se deshabilitan las bibliotecas de clases de Razor.
Agregue el siguiente JSON al archivo del proyecto:
<ItemGroup>
<Content Remove="wwwroot\**" />
</ItemGroup>
El código siguiente actualiza IWebHostEnvironment.WebRootPath
a un valor que no es de desarrollo, lo que garantiza que se devuelva contenido duplicado de wwwroot-custom
en lugar de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Por Rick Anderson y Kirk Larkin
Los archivos estáticos, como HTML, CSS, imágenes y JavaScript, son activos que una aplicación de ASP.NET Core proporciona directamente a los clientes de forma predeterminada.
Los archivos estáticos se almacenan en el directorio raíz web del proyecto. El directorio predeterminado es {content root}/wwwroot
, pero se puede cambiar con el método UseWebRoot. Para obtener más información, consulta Raíz del contenido y Raíz web.
El método CreateBuilder establece la raíz de contenido en el directorio actual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Se puede acceder a los archivos estáticos a través de una ruta de acceso relativa a la raíz web. Por ejemplo, las plantillas de proyecto Aplicación web contienen varias carpetas dentro de la carpeta wwwroot
:
wwwroot
css
js
lib
Considere la posibilidad de crear la carpeta wwwroot/images y agregar el archivo wwwroot/images/MyImage.jpg
. El formato del URI para acceder a un archivo en la carpeta images
es https://<hostname>/images/<image_file_name>
. Por ejemplo: https://localhost:5001/images/MyImage.jpg
Las plantillas de aplicación web predeterminadas llaman al método UseStaticFiles en Program.cs
, que permite proporcionar archivos estáticos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
La sobrecarga del método UseStaticFiles
sin parámetros marca los archivos en la raíz web como que se pueden proporcionar. El siguiente marcado hace referencia a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
En el marcado anterior, el carácter de tilde de la ñ ~
apunta a la raíz web.
Considere una jerarquía de directorios en la que residen fuera de la raíz web los archivos estáticos que se van a proporcionar:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una solicitud puede acceder al archivo red-rose.jpg
configurando el middleware de archivos estáticos como se muestra a continuación:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
En el código anterior, la jerarquía del directorio MyStaticFiles se expone públicamente a través del segmento de URI StaticFiles. Una solicitud a https://<hostname>/StaticFiles/images/red-rose.jpg
sirve al archivo red-rose.jpg
.
El siguiente marcado hace referencia a MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para entregar archivos desde varias ubicaciones, vea Entrega de archivos desde varias ubicaciones.
Se puede usar un objeto StaticFileOptions para establecer encabezados de respuesta HTTP. Además de configurar el servicio de archivos estáticos desde la raíz web, el código siguiente establece el encabezado Cache-Control:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
El código anterior hace que los archivos estáticos estén disponibles públicamente en la memoria caché local durante una semana (604800 segundos).
Las plantillas de ASP.NET Core llaman a UseStaticFiles antes de llamar a UseAuthorization. La mayoría de las aplicaciones siguen este patrón. Cuando se llama al middleware de archivos estáticos antes de al middleware de autorización:
wwwroot
, son accesibles públicamente.Para proporcionar archivos estáticos según su autorización:
wwwroot
.UseStaticFiles
, especificando una ruta de acceso, después de llamar a UseAuthorization
.using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
En el código anterior, la directiva de autorización de reserva requiere que se autentiquen todos los usuarios. Los puntos de conexión como los controladores, Razor Pages, etc. que especifican sus propios requisitos de autorización no usan la directiva de autorización de reserva. Por ejemplo, Razor Pages, controladores o métodos de acción con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usan el atributo de autorización aplicado en lugar de la directiva de autorización de reserva.
RequireAuthenticatedUser agrega DenyAnonymousAuthorizationRequirement a la instancia actual, lo que exige que el usuario actual se autentique.
Los recursos estáticos en wwwroot
son accesibles públicamente porque se llama al middleware de archivos estáticos predeterminado (app.UseStaticFiles();
) antes de a UseAuthentication
. Los recursos estáticos de la carpeta MyStaticFiles requieren autenticación. En el código de ejemplo se muestra esto.
Un enfoque alternativo a proporcionar archivos según la autorización es:
wwwroot
y cualquier directorio al que el middleware de archivos estáticos tenga acceso.[Authorize]
public class BannerImageModel : PageModel
{
private readonly IWebHostEnvironment _env;
public BannerImageModel(IWebHostEnvironment env) =>
_env = env;
public PhysicalFileResult OnGet()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
}
El examen de directorios permite enumerar directorios dentro de los directorios especificados.
Por motivos de seguridad, el examen de directorios está deshabilitado de forma predeterminada. Para obtener más información, consulta Consideraciones de seguridad para archivos estáticos.
Habilita el examen de directorios con AddDirectoryBrowser y UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
El código anterior permite el examen de directorios de la carpeta wwwroot/images usando la dirección URL https://<hostname>/MyImages
, con vínculos a cada archivo y carpeta:
AddDirectoryBrowser
agrega servicios requeridos por el middleware de examen de directorios, incluido HtmlEncoder. Estos servicios se pueden agregar mediante otras llamadas, como AddRazorPages, pero se recomienda llamar a AddDirectoryBrowser
para asegurarse de que los servicios se agregan en todas las aplicaciones.
El establecimiento de una página predeterminada proporciona a los visitantes un punto inicial en un sitio. Para servir un archivo predeterminado desde wwwroot
sin necesidad de que la dirección URL de la solicitud incluya el nombre del archivo, llame al método UseDefaultFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Debe llamarse a UseDefaultFiles
antes de a UseStaticFiles
para proporcionar el archivo predeterminado. UseDefaultFiles
es un sistema de reescritura de direcciones URL que no proporciona el archivo.
Con UseDefaultFiles
, las solicitudes a una carpeta en wwwroot
buscan:
default.htm
default.html
index.htm
index.html
El primer archivo que se encuentra en la lista se sirve como si la solicitud incluyera el nombre de archivo. La dirección URL del explorador sigue reflejando el URI solicitado.
El código siguiente cambia el nombre de archivo predeterminado a mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer combina la funcionalidad de UseStaticFiles
y UseDefaultFiles
y, opcionalmente, la de UseDirectoryBrowser
.
Llama a app.UseFileServer
para poder proporcionar archivos estáticos y el archivo predeterminado. El examen de directorios no está habilitado:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Ten en cuenta la siguiente jerarquía de directorios:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios de MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Se debe llamar a AddDirectoryBrowser cuando el valor de la propiedad EnableDirectoryBrowsing
es true
.
Al usar la jerarquía de archivos y el código anteriores, las direcciones URL se resuelven como se indica a continuación:
Identificador URI | Respuesta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Si no existe ningún archivo con el nombre predeterminado en el directorio MyStaticFiles, https://<hostname>/StaticFiles
devuelve la lista de directorios con vínculos activos:
UseDefaultFiles y UseDirectoryBrowser realizan un redireccionamiento del lado cliente desde el URI de destino sin una /
final hasta el URI de destino una /
final. Por ejemplo, desde https://<hostname>/StaticFiles
hasta https://<hostname>/StaticFiles/
. Las direcciones URL relativas dentro del directorio StaticFiles no son válidas sin una barra diagonal final (/
), a menos que se use la opción RedirectToAppendTrailingSlash de DefaultFilesOptions.
La clase FileExtensionContentTypeProvider contiene una propiedad Mappings
que actúa como una asignación de extensiones de archivo para tipos de contenido MIME. En el ejemplo siguiente, se asignan varias extensiones de archivo a los tipos MIME conocidos. Se reemplaza la extensión .rtf y se quita .mp4:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Consulta Tipos de contenido MIME.
El middleware de archivos estáticos entiende casi 400 tipos de contenido de archivo conocidos. Si el usuario solicita un archivo con un tipo de archivo desconocido, el middleware de archivos estáticos pasa la solicitud al siguiente middleware de la canalización. Si ningún middleware se ocupa de la solicitud, se devuelve una respuesta 404 No encontrado. Si se habilita la exploración de directorios, se muestra un vínculo al archivo en una lista de directorios.
El código siguiente permite proporcionar tipos desconocidos y procesa el archivo desconocido como una imagen:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Con el código anterior, una solicitud para un archivo con un tipo de contenido desconocido se devuelve como una imagen.
Advertencia
Habilitar ServeUnknownFileTypes supone un riesgo para la seguridad. Está deshabilitado de forma predeterminada y no se recomienda su uso. FileExtensionContentTypeProvider proporciona una alternativa más segura a ofrecer archivos con extensiones no estándar.
Tenga en cuenta la página Razor siguiente que muestra el archivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
y UseFileServer
tienen como valor predeterminado el proveedor de archivos que apunta a wwwroot
. Se pueden proporcionar instancias adicionales de UseStaticFiles
y UseFileServer
con otros proveedores de archivos para proporcionar archivos desde otras ubicaciones. En el ejemplo siguiente se llama a UseStaticFiles
dos veces para entregar archivos desde wwwroot
y MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Con el código anterior:
/MyStaticFiles/image3.png
.WebRootFileProvider
no se ha actualizado para incluir la carpeta MyStaticFiles
.El código siguiente actualiza WebRootFileProvider
, que permite al asistente de etiquetas de imagen proporcionar una versión:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Advertencia
UseDirectoryBrowser
y UseStaticFiles
pueden producir pérdidas de información confidencial. Se recomienda deshabilitar el examen de directorios en producción. Revisa cuidadosamente los directorios que se habilitan mediante UseStaticFiles
o UseDirectoryBrowser
. Todo el directorio y sus subdirectorios pasan a ser accesibles públicamente. Almacena los archivos adecuados para proporcionarlos al público en un directorio dedicado, como <content_root>/wwwroot
. Separa estos archivos de las vistas MVC, de Razor Pages, de los archivos de configuración, etc.
Las direcciones URL para el contenido que se expone a través de UseDirectoryBrowser
y UseStaticFiles
están sujetas a la distinción entre mayúsculas y minúsculas, y a restricciones de caracteres del sistema de archivos subyacente. Por ejemplo, Windows no distingue entre mayúsculas y minúsculas, pero macOS y Linux sí.
Las aplicaciones de ASP.NET Core hospedadas en IIS usan el módulo de ASP.NET Core para reenviar todas las solicitudes a la aplicación, incluidas las solicitudes de archivos estáticos. No se utiliza el controlador de archivos estáticos de IIS y no tiene la posibilidad de controlar las solicitudes.
Completa los pasos siguientes en el Administrador de IIS para quitar el controlador de archivos estáticos de IIS en el nivel de servidor o de sitio web:
Advertencia
Si el controlador de archivos estáticos de IIS está habilitado y el módulo de ASP.NET Core no está configurado correctamente, se proporcionan archivos estáticos. Esto sucede, por ejemplo, si el archivo web.config no está implementado.
.cs
y .cshtml
) fuera de la raíz web del proyecto de la aplicación. Por lo tanto, se crea una separación lógica entre el contenido del lado cliente de la aplicación y el código basado en servidor. Esto impide que se filtre el código del lado servidor.Cuando IWebHostEnvironment.WebRootPath se establece en una carpeta distinta de wwwroot
:
wwwroot
y en la propiedad IWebHostEnvironment.WebRootPath
actualizada se proporcionan desde wwwroot
.IWebHostEnvironment.WebRootPath
actualizada.Considera una aplicación web creada con la plantilla web vacía:
Que contenga un archivo Index.html
en wwwroot
y wwwroot-custom
.
Con el siguiente archivo Program.cs
actualizado que establece WebRootPath = "wwwroot-custom"
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Look for static files in "wwwroot-custom"
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
En el código anterior, las solicitudes a /
:
wwwroot/Index.html
wwwroot-custom/Index.html
Para asegurarte de que se devuelven los recursos de wwwroot-custom
, usa uno de los enfoques siguientes:
Elimina los recursos con nombre duplicado en wwwroot
.
Establece "ASPNETCORE_ENVIRONMENT"
de Properties/launchSettings.json
en cualquier valor distinto de "Development"
.
Deshabilita completamente los recursos web estáticos estableciendo <StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
en el archivo del proyecto. ADVERTENCIA, al deshabilitar los recursos web estáticos, se deshabilitan las bibliotecas de clases de Razor.
Agregue el siguiente JSON al archivo del proyecto:
<ItemGroup>
<Content Remove="wwwroot\**" />
</ItemGroup>
El código siguiente actualiza IWebHostEnvironment.WebRootPath
a un valor que no es de desarrollo, lo que garantiza que se devuelva contenido duplicado de wwwroot-custom
en lugar de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Por Rick Anderson y Kirk Larkin
Los archivos estáticos, como HTML, CSS, imágenes y JavaScript, son activos que una aplicación de ASP.NET Core proporciona directamente a los clientes de forma predeterminada.
Consulta o descarga el código de ejemplo (cómo descargarlo)
Los archivos estáticos se almacenan en el directorio raíz web del proyecto. El directorio predeterminado es {content root}/wwwroot
, pero se puede cambiar con el método UseWebRoot. Para obtener más información, consulta Raíz del contenido y Raíz web.
El método CreateDefaultBuilder establece la raíz de contenido en el directorio actual:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
El código anterior se creó con la plantilla de la aplicación web.
Se puede acceder a los archivos estáticos a través de una ruta de acceso relativa a la raíz web. Por ejemplo, las plantillas de proyecto Aplicación web contienen varias carpetas dentro de la carpeta wwwroot
:
wwwroot
css
js
lib
Considere la posibilidad de crear la carpeta wwwroot/images y agregar el archivo wwwroot/images/MyImage.jpg
. El formato del URI para acceder a un archivo en la carpeta images
es https://<hostname>/images/<image_file_name>
. Por ejemplo: https://localhost:5001/images/MyImage.jpg
Las plantillas de aplicación web predeterminadas llaman al método UseStaticFiles en Startup.Configure
, que permite proporcionar archivos estáticos:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
La sobrecarga del método UseStaticFiles
sin parámetros marca los archivos en la raíz web como que se pueden proporcionar. El siguiente marcado hace referencia a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
En el código anterior, el carácter de tilde de la ñ ~/
apunta a la raíz web.
Considere una jerarquía de directorios en la que residen fuera de la raíz web los archivos estáticos que se van a proporcionar:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Una solicitud puede acceder al archivo red-rose.jpg
configurando el middleware de archivos estáticos como se muestra a continuación:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
En el código anterior, la jerarquía del directorio MyStaticFiles se expone públicamente a través del segmento de URI StaticFiles. Una solicitud a https://<hostname>/StaticFiles/images/red-rose.jpg
sirve al archivo red-rose.jpg
.
El siguiente marcado hace referencia a MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Se puede usar un objeto StaticFileOptions para establecer encabezados de respuesta HTTP. Además de configurar el servicio de archivos estáticos desde la raíz web, el código siguiente establece el encabezado Cache-Control
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
const string cacheMaxAge = "604800";
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
// using Microsoft.AspNetCore.Http;
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAge}");
}
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
El código anterior establece la antigüedad máxima en 604 800 segundos (7 días).
Las plantillas de ASP.NET Core llaman a UseStaticFiles antes de llamar a UseAuthorization. La mayoría de las aplicaciones siguen este patrón. Cuando se llama al middleware de archivos estáticos antes de al middleware de autorización:
wwwroot
, son accesibles públicamente.Para proporcionar archivos estáticos según su autorización:
wwwroot
.UseStaticFiles
, especificando una ruta de acceso, después de llamar a UseAuthorization
.public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
// Remaining code ommitted for brevity.
En el código anterior, la directiva de autorización de reserva requiere que se autentiquen todos los usuarios. Los puntos de conexión como los controladores, Razor Pages, etc. que especifican sus propios requisitos de autorización no usan la directiva de autorización de reserva. Por ejemplo, Razor Pages, controladores o métodos de acción con [AllowAnonymous]
o [Authorize(PolicyName="MyPolicy")]
usan el atributo de autorización aplicado en lugar de la directiva de autorización de reserva.
RequireAuthenticatedUser agrega DenyAnonymousAuthorizationRequirement a la instancia actual, lo que exige que el usuario actual se autentique.
Los recursos estáticos en wwwroot
son accesibles públicamente porque se llama al middleware de archivos estáticos predeterminado (app.UseStaticFiles();
) antes de a UseAuthentication
. Los recursos estáticos de la carpeta MyStaticFiles requieren autenticación. En el código de ejemplo se muestra esto.
Un enfoque alternativo a proporcionar archivos según la autorización es:
wwwroot
y cualquier directorio al que el middleware de archivos estáticos tenga acceso.[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
El examen de directorios permite enumerar directorios dentro de los directorios especificados.
Por motivos de seguridad, el examen de directorios está deshabilitado de forma predeterminada. Para obtener más información, consulta Consideraciones de seguridad para archivos estáticos.
Habilite el examen de directorios con:
Startup.ConfigureServices
.Startup.Configure
.public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
El código anterior permite el examen de directorios de la carpeta wwwroot/images usando la dirección URL https://<hostname>/MyImages
, con vínculos a cada archivo y carpeta:
El establecimiento de una página predeterminada proporciona a los visitantes un punto inicial en un sitio. Para servir un archivo predeterminado desde wwwroot
sin necesidad de que la dirección URL de la solicitud incluya el nombre del archivo, llame al método UseDefaultFiles:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Debe llamarse a UseDefaultFiles
antes de a UseStaticFiles
para proporcionar el archivo predeterminado. UseDefaultFiles
es un sistema de reescritura de direcciones URL que no proporciona el archivo.
Con UseDefaultFiles
, las solicitudes a una carpeta en wwwroot
buscan:
default.htm
default.html
index.htm
index.html
El primer archivo que se encuentra en la lista se sirve como si la solicitud incluyera el nombre de archivo. La dirección URL del explorador sigue reflejando el URI solicitado.
El código siguiente cambia el nombre de archivo predeterminado a mydefault.html
:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
El código siguiente muestra Startup.Configure
con el código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
UseFileServer combina la funcionalidad de UseStaticFiles
y UseDefaultFiles
y, opcionalmente, la de UseDirectoryBrowser
.
Llama a app.UseFileServer
para poder proporcionar archivos estáticos y el archivo predeterminado. El examen de directorios no está habilitado. El código siguiente muestra Startup.Configure
con UseFileServer
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios:
app.UseFileServer(enableDirectoryBrowsing: true);
El código siguiente muestra Startup.Configure
con el código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Ten en cuenta la siguiente jerarquía de directorios:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
El código siguiente permite proporcionar archivos estáticos, el archivo predeterminado y el examen de directorios de MyStaticFiles
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // For the wwwroot folder.
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Se debe llamar a AddDirectoryBrowser cuando el valor de la propiedad EnableDirectoryBrowsing
es true
.
Al usar la jerarquía de archivos y el código anterior, las direcciones URL se resuelven como se indica a continuación:
Identificador URI | Respuesta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Si no existe ningún archivo con el nombre predeterminado en el directorio MyStaticFiles, https://<hostname>/StaticFiles
devuelve la lista de directorios con vínculos activos:
UseDefaultFiles y UseDirectoryBrowser realizan un redireccionamiento del lado cliente desde el URI de destino sin una /
final hasta el URI de destino una /
final. Por ejemplo, desde https://<hostname>/StaticFiles
hasta https://<hostname>/StaticFiles/
. Las direcciones URL relativas dentro del directorio StaticFiles no son válidas sin una barra diagonal final (/
).
La clase FileExtensionContentTypeProvider contiene una propiedad Mappings
que actúa como una asignación de extensiones de archivo para tipos de contenido MIME. En el ejemplo siguiente, se asignan varias extensiones de archivo a los tipos MIME conocidos. Se reemplaza la extensión .rtf y se quita .mp4:
// using Microsoft.AspNetCore.StaticFiles;
// using Microsoft.Extensions.FileProviders;
// using System.IO;
// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
El código siguiente muestra Startup.Configure
con el código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.AspNetCore.StaticFiles;
// using Microsoft.Extensions.FileProviders;
// using System.IO;
// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Consulta Tipos de contenido MIME.
El middleware de archivos estáticos entiende casi 400 tipos de contenido de archivo conocidos. Si el usuario solicita un archivo con un tipo de archivo desconocido, el middleware de archivos estáticos pasa la solicitud al siguiente middleware de la canalización. Si ningún middleware se ocupa de la solicitud, se devuelve una respuesta 404 No encontrado. Si se habilita la exploración de directorios, se muestra un vínculo al archivo en una lista de directorios.
El código siguiente permite proporcionar tipos desconocidos y procesa el archivo desconocido como una imagen:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
El código siguiente muestra Startup.Configure
con el código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Con el código anterior, una solicitud para un archivo con un tipo de contenido desconocido se devuelve como una imagen.
Advertencia
Habilitar ServeUnknownFileTypes supone un riesgo para la seguridad. Está deshabilitado de forma predeterminada y no se recomienda su uso. FileExtensionContentTypeProvider proporciona una alternativa más segura a ofrecer archivos con extensiones no estándar.
UseStaticFiles
y UseFileServer
tienen como valor predeterminado el proveedor de archivos que apunta a wwwroot
. Se pueden proporcionar instancias adicionales de UseStaticFiles
y UseFileServer
con otros proveedores de archivos para proporcionar archivos desde otras ubicaciones. Para más información, consulte este problema de GitHub.
Advertencia
UseDirectoryBrowser
y UseStaticFiles
pueden producir pérdidas de información confidencial. Se recomienda deshabilitar el examen de directorios en producción. Revisa cuidadosamente los directorios que se habilitan mediante UseStaticFiles
o UseDirectoryBrowser
. Todo el directorio y sus subdirectorios pasan a ser accesibles públicamente. Almacena los archivos adecuados para proporcionarlos al público en un directorio dedicado, como <content_root>/wwwroot
. Separa estos archivos de las vistas MVC, de Razor Pages, de los archivos de configuración, etc.
Las direcciones URL para el contenido que se expone a través de UseDirectoryBrowser
y UseStaticFiles
están sujetas a la distinción entre mayúsculas y minúsculas, y a restricciones de caracteres del sistema de archivos subyacente. Por ejemplo, Windows no distingue entre mayúsculas y minúsculas, pero macOS y Linux sí.
Las aplicaciones de ASP.NET Core hospedadas en IIS usan el módulo de ASP.NET Core para reenviar todas las solicitudes a la aplicación, incluidas las solicitudes de archivos estáticos. No se utiliza el controlador de archivos estáticos de IIS y no tiene la posibilidad de controlar las solicitudes.
Completa los pasos siguientes en el Administrador de IIS para quitar el controlador de archivos estáticos de IIS en el nivel de servidor o de sitio web:
Advertencia
Si el controlador de archivos estáticos de IIS está habilitado y el módulo de ASP.NET Core no está configurado correctamente, se proporcionan archivos estáticos. Esto sucede, por ejemplo, si el archivo web.config no está implementado.
.cs
y .cshtml
) fuera de la raíz web del proyecto de la aplicación. Por lo tanto, se crea una separación lógica entre el contenido del lado cliente de la aplicación y el código basado en servidor. Esto impide que se filtre el código del lado servidor.Comentarios de ASP.NET Core
ASP.NET Core es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios:
Eventos
Campeonato mundial de DataViz de Power BI
14 feb, 16 - 31 mar, 16
Con 4 posibilidades de entrar, podrías ganar un paquete de conferencia y convertirlo en el Live Grand Finale en Las Vegas
Saber másCursos
Ruta de aprendizaje
Azure Static Web Apps - Training
Azure Static Web Apps es un servicio de aplicaciones web modernas que ofrece un desarrollo de pila completa optimizado desde el código fuente hasta la alta disponibilidad global.