# ASP.NET Core
> Paquete NuGet con un middleware para aplicaciones ASP.NET Core (.NET 8 o superior).
Página original: https://docs.jazui.com/integrations/aspnetcore/es
Si tu SPA (Blazor WebAssembly, Angular, React, Vue…) la sirve una aplicación ASP.NET Core, `Jazui.AspNetCore` añade un middleware que atiende a los bots antes de los archivos estáticos y del *fallback* a `index.html`. Es la opción recomendada también en IIS cuando la aplicación es de .NET.
## Antes de empezar
- .NET 8 o superior.
- Tu sitio verificado en Jazui y tu token.
- El origen de paquetes de AstrolUI (`https://nuget.astrolui.com/v3/index.json`) añadido a NuGet.
## Instalación
`Jazui.AspNetCore` no está en nuget.org: se publica en el **repositorio de paquetes NuGet de AstrolUI**, `https://nuget.astrolui.com/v3/index.json`. Añade ese origen una vez (en Visual Studio, con la línea de comandos o en un `nuget.config`) y después instala el paquete como cualquier otro. El paquete lleva el logo de Jazui y su versión sigue la de .NET con la que se publica (por ejemplo `10.0.13.1`); funciona en aplicaciones de .NET 8 o superior.
### En Visual Studio
1. Abre **Herramientas › Opciones › Administrador de paquetes NuGet › Orígenes de paquetes**.
2. Pulsa **+**, escribe **Nombre**: `AstrolUI` y **Origen**: `https://nuget.astrolui.com/v3/index.json`, pulsa **Actualizar** y después **Aceptar**.
3. Con el botón derecho sobre tu proyecto, elige **Administrar paquetes NuGet…**.
4. Arriba a la derecha, en **Origen del paquete**, elige `AstrolUI` (o **Todo**).
5. En **Examinar**, busca `Jazui.AspNetCore`, elige la última versión y pulsa **Instalar**.
> Si tu solución tiene un `nuget.config` con ``, Visual Studio solo usa los orígenes de ese archivo: añade AstrolUI ahí (abajo tienes el ejemplo).
### Con la línea de comandos
```bash
dotnet nuget add source https://nuget.astrolui.com/v3/index.json --name AstrolUI
dotnet add package Jazui.AspNetCore
```
### Con nuget.config
Para que todo el equipo y tu integración continua lo tengan sin configurar nada, pon un `nuget.config` junto a tu solución. Si ya usas la **asignación de orígenes** (`packageSourceMapping`), añade el patrón `Jazui.*` al origen AstrolUI; si no, basta con `packageSources`.
`nuget.config`:
```xml
```
## Configuración
Registra el servicio y añade el middleware **antes** de `UseStaticFiles` y del `MapFallbackToFile`:
`Program.cs`:
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddJazui(builder.Configuration);
var app = builder.Build();
app.UseForwardedHeaders(); // solo si hay un proxy o CDN delante: la IP y el esquema del bot
app.UseJazui(); // antes de los archivos estáticos y del fallback de la SPA
app.UseStaticFiles();
app.MapFallbackToFile("index.html");
app.Run();
```
`appsettings.json`:
```json
{
"Jazui": {
"Token": "",
"SiteUrl": ""
}
}
```
No pongas el token en `appsettings.json`: en producción usa la variable de entorno `Jazui__Token` (o los secretos de usuario en desarrollo). `UseForwardedHeaders` solo hace falta si hay un proxy o CDN delante, para que Jazui reciba la IP real del bot y el esquema `https`.
## Opciones
Todas se leen de la sección `Jazui` de la configuración y se pueden cambiar también en código:
| Opción | Por defecto | Para qué |
|---|---|---|
| `Token` | — | Token de la cuenta o del sitio. Sin token, el middleware no hace nada. |
| `ApiUrl` | `https://api.jazui.com` | Dirección de la API. |
| `SiteUrl` | — | Dominio público cuando la aplicación ve otro (proxy, pruebas). |
| `Timeout` | 20 s | Pasado este tiempo se sirve la página normal. |
| `ExcludedPaths` | `/api`, `/_framework`, `/_content`, `/_blazor` | Rutas que nunca pasan por Jazui (por segmento: `/api` cubre `/api/x` pero no `/apis`). |
| `ExtraBots` | — | Fragmentos de agente de usuario que se suman a la lista de bots. |
| `RemoteBots` | `true` | Descarga la lista de bots de Jazui al arrancar y cada `BotsRefreshInterval`. |
| `BotsRefreshInterval` | 24 h | Cada cuánto se vuelve a descargar la lista. |
| `ReportUnknownBots` | `true` | Avisa a Jazui de los agentes con pinta de bot que no están en la lista (sin enviar la página). |
`Program.cs`:
```csharp
builder.Services.AddJazui(builder.Configuration, options =>
{
options.Timeout = TimeSpan.FromSeconds(10);
options.ExcludedPaths = ["/api", "/_framework", "/_content", "/_blazor", "/admin"];
options.ExtraBots = ["mibotinterno"];
options.BotsRefreshInterval = TimeSpan.FromHours(12);
});
```
## Qué hace
Para cada petición que es de un bot, llama a la API con la dirección (o `SiteUrl` más la ruta), el agente de usuario, la IP del bot (de `Connection.RemoteIpAddress`) y el `If-None-Match`. Si Jazui responde con `X-Jazui` o con un bloqueo, copia el código, las cabeceras y el cuerpo; si tarda o falla, lo apunta en el registro como aviso y sigue con el resto de la aplicación. La versión de la lista de bots en uso está en `JazuiMiddleware.BotsVersion`.
##
Pide tu portada como si fueras un bot, con el agente de usuario de pruebas integration-test:
curl -I -A "integration-test" https://misitio.com/
La respuesta debe llevar x-jazui: true y x-jazui-cache: MISS la primera vez y HIT después. Sin agente de bot (curl -I https://misitio.com/) debe llegar tu web de siempre, sin x-jazui. En el panel, la petición aparece en Tráfico de bots y la página en Páginas en caché.
Pide tu portada como si fueras un bot, con el agente de usuario de pruebas `integration-test`:
```
curl -I -A "integration-test" https://misitio.com/
```
La respuesta debe llevar `x-jazui: true` y `x-jazui-cache: MISS` la primera vez y `HIT` después. Sin agente de bot (`curl -I https://misitio.com/`) debe llegar tu web de siempre, sin `x-jazui`. En el panel, la petición aparece en **Tráfico de bots** y la página en **Páginas en caché**.
## Si algo no funciona
- **No se encuentra `Jazui.AspNetCore`**: falta el origen AstrolUI, o tu `nuget.config` tiene `` o una asignación de orígenes sin el patrón `Jazui.*`.
- **No aparece `x-jazui`**: `UseJazui()` tiene que ir antes de `UseStaticFiles()` y de `MapFallbackToFile`; revisa también que el token llega (variable `Jazui__Token`).
- **Detrás de IIS o de un proxy, la URL sale con `http`**: configura `UseForwardedHeaders` o define `SiteUrl`.
- **Los avisos del registro** («Jazui no respondió…») te dicen por qué se sirvió la página normal.