Redirect Non WWW to WWW using Asp.Net Core Middleware

我只是一个虾纸丫 提交于 2019-11-29 09:20:01

A reusable alternative would be to create a custom rewrite rule and a corresponsing extension method to add the rule to the rewrite options. This would be very similar to how AddRedirectToHttps works.

Custom Rule:

public class RedirectToWwwRule : IRule
{
    public virtual void ApplyRule(RewriteContext context)
    {
        var req = context.HttpContext.Request;
        if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }

        if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }

        var wwwHost = new HostString($"www.{req.Host.Value}");
        var newUrl = UriHelper.BuildAbsolute(req.Scheme, wwwHost, req.PathBase, req.Path, req.QueryString);
        var response = context.HttpContext.Response;
        response.StatusCode = 301;
        response.Headers[HeaderNames.Location] = newUrl;
        context.Result = RuleResult.EndResponse;
    }
}

Extension Method:

public static class RewriteOptionsExtensions
{
    public static RewriteOptions AddRedirectToWww(this RewriteOptions options)
    {
        options.Rules.Add(new RedirectToWwwRule());
        return options;
    }
}

Usage:

var options = new RewriteOptions();
options.AddRedirectToWww();
options.AddRedirectToHttps();
app.UseRewriter(options);

Future versions of the rewrite middleware will contain the rule and the corresponding extension method. See this pull request

I'm more of an Apache user and fortunately URL Rewriting Middleware in ASP.NET Core provides a method called AddApacheModRewrite to perform mod_rewrite rules on the fly.

1- Create a .txt file whatever the name and put these two lines into it:

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

2- then call it this way:

AddApacheModRewrite(env.ContentRootFileProvider, "Rules.txt")

Done!

Using just a regex,

Find ^(https?://)?((?!www\.)(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))

Replace $1www.$2

Expanded

 ^                             # BOS
 (                             # (1 start), optional http(s)
      https?  ://
 )?                            # (1 end)
 (                             # (2 start), domains without www prefix
      (?! www\. )
      (?:
           (?: [a-z\u00a1-\uffff0-9]+ -? )*
           [a-z\u00a1-\uffff0-9]+ 
      )
      (?:
           \.
           (?: [a-z\u00a1-\uffff0-9]+ -? )*
           [a-z\u00a1-\uffff0-9]+ 
      )*
      (?:
           \.
           (?: [a-z\u00a1-\uffff]{2,} )
      )
 )                             # (2 end)

It's unclear from if what AddRedirect method does and if it actually accepts regex.

But to insert a "www" to a url without "www"?
You could try it with these strings:

string pattern = @"^(https?://)(?!www[.])(.*)$";
string replacement = "$1www.$2";

//Regex rgx = new Regex(pattern);
//string redirectUrl = rgx.Replace(url, replacement);

Because of the negative lookahead (?!www[.]) after the protocol, it'll ignore strings like http://www.what.ever

$1 and $2 are the first and second capture groups.

I think instead of using Regex unless it is a must you can use the Uri class to reconstruct your url

var uri = new Uri("http://example.com/test/page.html?query=new&sortOrder=ASC");
var returnUri = $"{uri.Scheme}://www.{uri.Authority}
{string.Join(string.Empty, uri.Segments)}{uri.Query}";

And the result will look like

Output: http://www.example.com/test/page.html?query=new&sortOrder=ASC

Here's a regex to try:

(http)(s)?(:\/\/)[^www.][A-z0-9]+(.com|.gov|.org)

It will select URLs like:

  • http://example.com
  • https://example.com
  • http://example.gov
  • https://example.gov
  • http://example.org
  • https://example.org

But not like:

  • http://www.example.com
  • https://www.example.com

I prefer to use explicit extensions (e.g. .com, .gov, or .org) when possible, but you could also use something like this if it is beneficial to your use case:

(http)(s)?(:\/\/)[^www.][A-z0-9]+(.*){3}

I would then approach the replacement with something like the following:

Regex r = new Regex(@"(http)(s)?(:\/\/)[^www.][A-z0-9]+(.*){3}");
string test = @"http://example.org";
if (r.IsMatch(test))
{
    Console.WriteLine(test.Replace("https://", "https://www."));
    Console.WriteLine(test.Replace("http://", "http://www."));
}

You don't need a RegEx, just a simple replace will work:

var temp = new string[] {"http://google.com", "http://www.google.com", "http://gmail.com", "https://www.gmail.com", "https://example.com"};

var urlWithoutWWW = temp.Where(d => 
                         d.IndexOf("http://www") == -1 && d.IndexOf("https://www") == -1);

foreach (var newurl in urlWithoutWWW)
{
     Console.WriteLine(newurl.Replace("://", "://www."));
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!