ASP.NET Core

Paquete NuGet con un middleware para aplicaciones ASP.NET Core (.NET 8 o superior).

Markdown

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 <clear />, Visual Studio solo usa los orígenes de ese archivo: añade AstrolUI ahí (abajo tienes el ejemplo).

Con la línea de comandos

Terminal
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 version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="AstrolUI" value="https://nuget.astrolui.com/v3/index.json" protocolVersion="3" />
  </packageSources>
  <!-- Solo si usas la asignación de orígenes: los paquetes Jazui.* salen de AstrolUI -->
  <packageSourceMapping>
    <packageSource key="AstrolUI">
      <package pattern="Jazui.*" />
    </packageSource>
    <packageSource key="nuget.org">
      <package pattern="*" />
    </packageSource>
  </packageSourceMapping>
</configuration>

Configuración

Registra el servicio y añade el middleware antes de UseStaticFiles y del MapFallbackToFile:

Program.cs
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
{
  "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ónPor defectoPara qué
Token—Token de la cuenta o del sitio. Sin token, el middleware no hace nada.
ApiUrlhttps://api.jazui.comDirección de la API.
SiteUrl—Dominio público cuando la aplicación ve otro (proxy, pruebas).
Timeout20 sPasado este tiempo se sirve la página normal.
ExcludedPaths/api, /_framework, /_content, /_blazorRutas 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.
RemoteBotstrueDescarga la lista de bots de Jazui al arrancar y cada BotsRefreshInterval.
BotsRefreshInterval24 hCada cuánto se vuelve a descargar la lista.
ReportUnknownBotstrueAvisa a Jazui de los agentes con pinta de bot que no están en la lista (sin enviar la página).
Program.cs
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.

<p>Pide tu portada como si fueras un bot, con el agente de usuario de pruebas <code>integration-test</code>:</p><pre><code>curl -I -A "integration-test" https://misitio.com/</code></pre><p>La respuesta debe llevar <code>x-jazui: true</code> y <code>x-jazui-cache: MISS</code> la primera vez y <code>HIT</code> después. Sin agente de bot (<code>curl -I https://misitio.com/</code>) debe llegar tu web de siempre, sin <code>x-jazui</code>. En el panel, la petición aparece en <b>Tráfico de bots</b> y la página en <b>Páginas en caché</b>.</p>

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 <clear /> 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.