我已经看到您可以在ASP.NET Core 2.0中配置路由以生成小写网址,如下所述:https://stackoverflow.com/a/45777372/83825
使用此:
services.AddRouting(options => options.LowercaseUrls = true);
但是,尽管生成网址没什么问题,但它似乎没有做任何事情来实际执行它们,也就是说,将任何非全部小写的网址重定向到相应的小写网址(最好是通过301重定向) )。
我知道人们通过不同的网址访问我的网站,我希望他们永久都是小写的。
通过RewriteOptions和Regex进行标准重定向是唯一的方法吗?这样做的恰当表达方式是什么:
var options = new RewriteOptions().AddRedirect("???", "????");
还是有另一种方式吗?
答案 0 :(得分:5)
我感谢这已经有好几个月了,但是对于那些可能正在寻找相同解决方案的人来说,您可以添加一个实现public class RedirectLowerCaseRule : IRule
{
public int StatusCode { get; } = (int)HttpStatusCode.MovedPermanently;
public void ApplyRule(RewriteContext context)
{
HttpRequest request = context.HttpContext.Request;
PathString path = context.HttpContext.Request.Path;
HostString host = context.HttpContext.Request.Host;
if (path.HasValue && path.Value.Any(char.IsUpper) || host.HasValue && host.Value.Any(char.IsUpper))
{
HttpResponse response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[HeaderNames.Location] = (request.Scheme + "://" + host.Value + request.PathBase + request.Path).ToLower() + request.QueryString;
context.Result = RuleResult.EndResponse;
}
else
{
context.Result = RuleResult.ContinueRules;
}
}
}
的复杂重定向,例如:
Startup.cs
然后可以在Configure
new RewriteOptions().Add(new RedirectLowerCaseRule());
方法下应用此方法:
let quantity = 13;
let width = 2;
lengthft = document.getElementById('lengthft');
lengthin = document.getElementById('lengthin');
length = ((quantity / width)/1);
lengthft.value = (Math.floor(length)/1);
lengthin.value = (Math.ceil(((((length) - *lengthft.value*) * 100)/8).toFixed(2)));
if (lengthin.value >= 12) {
lengthft = lengthft.value = (lengthft + 1);
lengthin = lengthin.value = (lengthin - 12);
}
希望这有帮助!
答案 1 :(得分:0)
由于无法发表评论而添加为答案(尚未)。这是对Ben Maxfields答案的补充。
使用他的代码http://www.example.org/Example/example
不会被重定向,因为没有检查PathBase
的大写字母(即使它是用来构建新的小写URI)的。
因此,根据他的代码,我最终使用了此代码:
public class RedirectLowerCaseRule : IRule
{
public int StatusCode { get; } = (int)HttpStatusCode.MovedPermanently;
public void ApplyRule(RewriteContext context)
{
HttpRequest request = context.HttpContext.Request;
PathString path = context.HttpContext.Request.Path;
PathString pathbase = context.HttpContext.Request.PathBase;
HostString host = context.HttpContext.Request.Host;
if ((path.HasValue && path.Value.Any(char.IsUpper)) || (host.HasValue && host.Value.Any(char.IsUpper)) || (pathbase.HasValue && pathbase.Value.Any(char.IsUpper)))
{
Console.WriteLine("Redirect should happen");
HttpResponse response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[HeaderNames.Location] = (request.Scheme + "://" + host.Value + request.PathBase + request.Path).ToLower() + request.QueryString;
context.Result = RuleResult.EndResponse;
}
else
{
context.Result = RuleResult.ContinueRules;
}
}
}
答案 2 :(得分:0)
略有不同的实现方式,也受this other thread的启发。
public class RedirectLowerCaseRule : IRule
{
public void ApplyRule(RewriteContext context)
{
HttpRequest request = context.HttpContext.Request;
string url = request.Scheme + "://" + request.Host + request.PathBase + request.Path;
bool isGet = request.Method.ToLowerInvariant().Contains("get");
if ( isGet && url.Contains(".") == false && Regex.IsMatch(url, @"[A-Z]") )
{
HttpResponse response = context.HttpContext.Response;
response.Clear();
response.StatusCode = StatusCodes.Status301MovedPermanently;
response.Headers[HeaderNames.Location] = url.ToLowerInvariant() + request.QueryString;
context.Result = RuleResult.EndResponse;
}
else
{
context.Result = RuleResult.ContinueRules;
}
}
}
所做的更改对我有用:
使用ToLowerInvariant()
代替ToLower()
(请参阅可能的问题here)
保持端口号不变。
绕过GET以外的请求方法。
假设静态文件(如js / css / images等)应保留所有大写字母,请使用圆点绕过请求。
使用Microsoft.AspNetCore.Http.StatusCodes
。
答案 3 :(得分:0)
我的两分钱...基于https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/Rewrite/src/RedirectToWwwRule.cs
git ls-tree HEAD some/directory
使用扩展方法:
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);
}
}
其他注意事项是选择状态码。我在扩展方法中使用了307和308,因为它们可以防止在请求期间更改请求方法(例如,从GET更改为POST),但是,如果您希望允许这种行为,则可以使用301和302。请参见{{3} }以获取更多信息。
答案 4 :(得分:-2)
确定要重定向吗?如果不是,并且您的目标是在主机和路径中不存在大写字母,则可以使用以下IRule。这向我保证,无论我在哪里查看管道中的路径都是小写。
public class RewriteLowerCaseRule : IRule
{
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var host = request.Host;
var pathBase = request.PathBase;
var path = request.Path;
if (host.HasValue)
{
if (host.Port == null)
{
request.Host = new HostString(host.Host.ToLower());
}
else
{
request.Host = new HostString(host.Host.ToLower(), (int) host.Port);
}
}
if (pathBase.HasValue)
{
request.PathBase = new PathString(pathBase.Value.ToLower());
}
if (path.HasValue)
{
request.Path = new PathString(path.Value.ToLower());
request.PathBase = new PathString(pathBase.Value.ToLower());
}
context.Result = RuleResult.ContinueRules;
}
}
用法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseRewriter(new RewriteOptions().Add(new RewriteLowerCaseRule()));
...
}