将asp.net core 2.0 url重定向到小写

时间:2018-01-26 20:52:20

标签: url-redirection asp.net-core-2.0 lowercase

我已经看到您可以在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("???", "????");

还是有另一种方式吗?

5 个答案:

答案 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()));
    ...
}