Cómo usar Rewrite URL entre recursos en ASP.NET Core Web API – II
Previamente: Cómo usar Rewrite URL entre recursos en ASP.NET Core Web API – I
Método 3. Crear una regla
Una de las posibilidades que tenemos también es la de crear una regla implementando IRule.
La particularidad de crear una regla implementando IRule es que nos da muchísimo flexibilidad.
En mi caso, voy a crear una regla muy simple a modo de ejemplo sobre 410 Gone para mi recurso api/others.
Tendré que hacer uso de los siguientes ensamblados:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Rewrite; using System;
Y el código de una clase que he llamado ClientErrorRule quedará de la siguiente manera:
public class ClientErrorRule : IRule { public void ApplyRule(RewriteContext context) { var request = context.HttpContext.Request; if (request.Path.Value.Contains("api/others", StringComparison.OrdinalIgnoreCase)) { context.HttpContext.Response.StatusCode = StatusCodes.Status410Gone; context.Result = RuleResult.EndResponse; } } }
Para llamar a esta regla, dentro de Startup.cs escribiremos el siguiente código dentro del método Configure:
var rewrite = new RewriteOptions() .Add(new ClientErrorRule()); app.UseHttpsRedirection(); app.UseRewriter(rewrite); app.UseMvc();
Ejecutar este código se aproxima completamente a lo que deseamos realizar, e incluso podríamos escribir en log (si nos interesase) qué está sucediendo, o bien cualquier operación o acción compleja que quisiéramos ejecutar aquí dentro de la regla.
Método 4. Crear un acción
Otra posibilidad que tenemos es creando una acción.
Para ello, crearé una clase a la que he llamado ClientErrorAction.
Dentro de esta clase he agregado el siguiente código:
public static void ClientErrorRequests(RewriteContext context) { var request = context.HttpContext.Request; if (request.Path.Value.Contains("api/others", StringComparison.OrdinalIgnoreCase)) { context.HttpContext.Response.StatusCode = StatusCodes.Status410Gone; context.Result = RuleResult.EndResponse; } }
Para llamar a esta acción, dentro de Startup.cs escribiremos el siguiente código dentro del método Configure:
var rewrite = new RewriteOptions() .Add(ClientErrorAction.ClientErrorRequests); app.UseHttpsRedirection(); app.UseRewriter(rewrite); app.UseMvc();
Al ejecutar este código, veremos que se comporta tal y como esperábamos.
Método 5. Haciendo más sólida una regla (o acción)
Aunque aquí voy a mostrar cómo hacer más sólida una regla, esto sería aplicable igualmente para una acción.
Lo que voy a hacer básicamente, es coger el código de la regla y modificarlo para sea más flexible y extensible aún.
El código de nuestra regla ClientErrorRule que implementa a su vez IRule quedaría de la siguiente forma:
public class ClientErrorRule : IRule { private readonly TimeSpan _regexTimeout = TimeSpan.FromSeconds(1); private readonly Regex _initialMatch; private readonly int _statusCode; public ClientErrorRule(string regex, int statusCode) { if (string.IsNullOrEmpty(regex)) { throw new ArgumentException(nameof(regex)); } _initialMatch = new Regex(regex, RegexOptions.Compiled | RegexOptions.CultureInvariant, _regexTimeout); _statusCode = statusCode; } public void ApplyRule(RewriteContext context) { var path = context.HttpContext.Request.Path; Match initMatchResults = (path == PathString.Empty ? _initialMatch.Match(path.ToString()) : _initialMatch.Match(path.ToString().Substring(1))); if (initMatchResults.Success) { context.HttpContext.Response.StatusCode = _statusCode; context.Result = RuleResult.EndResponse; } } }
Luego, he creado un controlador nuevo denominado SamplesController para agregar en Startup tantas reglas como queramos.
En realidad, voy a hacer que OthersController y cualquier parte de la ruta api/others, me devuelva un 410.
Y por otro lado, que para SamplesController en api/samples me devuelva un 409.
El código de Startup quedará de esta manera:
var rewrite = new RewriteOptions() .Add(new ClientErrorRule("api/others", StatusCodes.Status410Gone)) .Add(new ClientErrorRule("api/samples", StatusCodes.Status409Conflict)); app.UseHttpsRedirection(); app.UseRewriter(rewrite); app.UseMvc();
Como podemos apreciar, se trata al igual que con AddRedirect de una forma muy limpia y clara de definir ciertas acciones de reescritura de una URL.
Espero que te haya ayudado.
Happy Coding!