URL Rewriting Middleware ASP.Net Core 2.0

前端 未结 2 1392
难免孤独
难免孤独 2020-12-21 12:39

I can\'t write correctly a URL Rewriting Middleware. I think the regex is correct. I use this functionality for the first time and maybe I do not understand something.

2条回答
  •  渐次进展
    2020-12-21 13:34

    based on this article: https://www.softfluent.com/blog/dev/Page-redirection-and-URL-Rewriting-with-ASP-NET-Core

    When you develop a web application, you often need to add some redirection rules. The most common redirection rules are: redirect from "http" to "https", add "www", or move a website to another domain. URL rewriting is often use to provide user friendly URL.

    I want to explain the difference between redirection and rewrite. Redirecting sends a HTTP 301 or 302 to the client, telling the client that it should access the page using another URL. The browser will update the URL visible in the address bar, and make a new request using the new URL. On the other hand, rewriting happens on the server, and is a translation of one URL to another. The server will use the new URL to process the request. The client doesn't know that the server has rewritten the URL.

    With IIS, you can use the web.config file to define the redirection and rewrite rules or use RewritePath:

    
    
      
        
          
            
              
              
                
                
                
              
              
            
          
        
      
    
    

    However, this doesn't work anymore with ASP.NET Core. Instead, you can use the new NuGet package: Microsoft.AspNetCore.Rewrite (GitHub). This package is very easy to use. Open the startup.cs file and edit the Configure method:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ISiteProvider siteProvider)
    {           
        app.UseRewriter(new RewriteOptions()
            .AddRedirectToHttps()
            .AddRedirect(@"^section1/(.*)", "new/$1", (int)HttpStatusCode.Redirect)
            .AddRedirect(@"^section2/(\\d+)/(.*)", "new/$1/$2", (int)HttpStatusCode.MovedPermanently)
            .AddRewrite("^feed$", "/?format=rss", skipRemainingRules: false));
    
        app.UseStaticFiles();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    

    The rules are based on regex and substitutions. The regex is evaluated on the HttpContext.Request.Path, which does not include the domain, nor the protocol. This means you cannot redirect to another domain or add "www" using this method, but don't worry, I will show you how to do this after!

    Microsoft has decided to help you using this new package. Indeed, if you already have a web.config file or even an .htaccess file (.net core is cross platform) you can import them directly:

    app.UseRewriter(new RewriteOptions()
        .AddIISUrlRewrite(env.ContentRootFileProvider, "web.config")
        .AddApacheModRewrite(env.ContentRootFileProvider, ".htaccess"));
    

    If you have complex rules that can't be expressed using a regex, you can write your own rule. A rule is a class that implements Microsoft.AspNetCore.Rewrite.IRule:

    // app.UseRewriter(new RewriteOptions().Add(new RedirectWwwRule()));
    
    public class RedirectWwwRule : Microsoft.AspNetCore.Rewrite.IRule
    {
        public int StatusCode { get; } = (int)HttpStatusCode.MovedPermanently;
        public bool ExcludeLocalhost { get; set; } = true;
    
        public void ApplyRule(RewriteContext context)
        {
            var request = context.HttpContext.Request;
            var host = request.Host;
            if (host.Host.StartsWith("www", StringComparison.OrdinalIgnoreCase))
            {
                context.Result = RuleResult.ContinueRules;
                return;
            }
    
            if (ExcludeLocalhost && string.Equals(host.Host, "localhost", StringComparison.OrdinalIgnoreCase))
            {
                context.Result = RuleResult.ContinueRules;
                return;
            }
    
            string newPath = request.Scheme + "://www." + host.Value + request.PathBase + request.Path + request.QueryString;
    
            var response = context.HttpContext.Response;
            response.StatusCode = StatusCode;
            response.Headers[HeaderNames.Location] = newPath;
            context.Result = RuleResult.EndResponse; // Do not continue processing the request        
        }
    }
    

提交回复
热议问题