我的看法...基于https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/Rewrite/src/RedirectToWwwRule.cs
public class RedirectToLowercaseRule : IRule
{
private readonly int _statusCode;
public RedirectToLowercaseRule(int statusCode)
{
_statusCode = statusCode;
}
public void ApplyRule(RewriteContext context)
{
var req = context.HttpContext.Request;
if (!req.Scheme.Any(char.IsUpper)
&& !req.Host.Value.Any(char.IsUpper)
&& !req.PathBase.Value.Any(char.IsUpper)
&& !req.Path.Value.Any(char.IsUpper))
{
context.Result = RuleResult.ContinueRules;
return;
}
var newUrl = UriHelper.BuildAbsolute(req.Scheme.ToLowerInvariant(), new HostString(req.Host.Value.ToLowerInvariant()), req.PathBase.Value.ToLowerInvariant(), req.Path.Value.ToLowerInvariant(), req.QueryString);
var response = context.HttpContext.Response;
response.StatusCode = _statusCode;
response.Headers[HeaderNames.Location] = newUrl;
context.Result = RuleResult.EndResponse;
context.Logger.RedirectedToLowercase();
}
}
使用扩展方法:
public static class RewriteOptionsExtensions
{
public static RewriteOptions AddRedirectToLowercase(this RewriteOptions options, int statusCode)
{
options.Add(new RedirectToLowercaseRule(statusCode));
return options;
}
public static RewriteOptions AddRedirectToLowercase(this RewriteOptions options)
{
return AddRedirectToLowercase(options, StatusCodes.Status307TemporaryRedirect);
}
public static RewriteOptions AddRedirectToLowercasePermanent(this RewriteOptions options)
{
return AddRedirectToLowercase(options, StatusCodes.Status308PermanentRedirect);
}
}
以及日志记录:
internal static class MiddlewareLoggingExtensions
{
private static readonly Action<ILogger, Exception> _redirectedToLowercase = LoggerMessage.Define(LogLevel.Information, new EventId(1, "RedirectedToLowercase"), "Request redirected to lowercase");
public static void RedirectedToLowercase(this ILogger logger)
{
_redirectedToLowercase(logger, null);
}
}
使用方法:
app.UseRewriter(new RewriteOptions()
.AddRedirectToLowercase());
其他考虑因素包括状态码的选择。 在扩展方法中,我使用了307和308,因为它们可以防止在请求期间更改请求方法(例如从GET到POST)。 但是,如果您希望允许该行为,则可以使用301和302。 有关详细信息,请参见HTTP 301与308状态代码有何区别?
Microsoft.AspNetCore.Http
中,有一个StatusCodes
枚举类型,你可以使用它来代替(int)HttpStatusCode.XXX
。每个枚举名称中都包含状态码数字,例如StatusCodes.Status301MovedPermanently
。 - CtrlDotrequest.PathBase + request.Path
隐式地转换为request.PathBase.ToString() + request.Path.ToString()
,这将导致非 ASCII 字符的转义。相反,请使用request.PathBase.Value + request.Path.Value
以防止不必要的转义。 - DhyMik