Area and subdomain routing

前端 未结 5 822
遇见更好的自我
遇见更好的自我 2021-01-06 09:34

I created Admin Area inside my ASP.NET Core application and updated my routes like that:

app.UseMvc(routes =>
{
    routes.MapRoute(name: \"areaRoute\",
          


        
相关标签:
5条回答
  • 2021-01-06 09:43

    I finally got this working in .Net Core 2.1

    Created a new router

    public class SubdomainAreaRouter : MvcRouteHandler, IRouter
    {
        public SubdomainAreaRouter(IActionInvokerFactory actionInvokerFactory, IActionSelector actionSelector, DiagnosticSource diagnosticSource, ILoggerFactory loggerFactory) : base(actionInvokerFactory, actionSelector, diagnosticSource, loggerFactory)
        {
        }
    
        public SubdomainAreaRouter(IActionInvokerFactory actionInvokerFactory, IActionSelector actionSelector, DiagnosticSource diagnosticSource, ILoggerFactory loggerFactory, IActionContextAccessor actionContextAccessor) : base(actionInvokerFactory, actionSelector, diagnosticSource, loggerFactory, actionContextAccessor)
        {
        }
    
        public new async Task RouteAsync(RouteContext context)
        {
            string url = context.HttpContext.Request.Headers["HOST"];
            var splittedUrl = url.Split('.');
    
            if (splittedUrl != null && (splittedUrl.Length > 0 && splittedUrl[0] == "admin"))
            {
                context.RouteData.Values.Add("area", "Admin");
            }
    
            await base.RouteAsync(context);
        }
    }
    

    In Startup.cs, add the following into the ConfigureServices method:

    services.AddSingleton<SubdomainAreaRouter>();
    

    In Startup.cs, pass in your new router into the Configure method and update the UseMvc logic to use your new router:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, SubdomainAreaRouter subdomainRouter)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
    
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSession();
        app.UseCookiePolicy();
    
        app.UseMvc(routes =>
        {
            routes.DefaultHandler = subdomainRouter;
            routes.MapRoute(
                "admin",
                "{area:exists}/{controller=Home}/{action=Index}/{id?}");
            routes.MapRoute(
                "default",
                "{controller=Home}/{action=Index}/{id?}");
        });
    }
    
    0 讨论(0)
  • 2021-01-06 09:48

    Good solution Sergio was able to create the subdomain routing. Just to add to your solution and to complete the subdomain route to the physical directory.

        public class HomeController : Controller
        {
            public async Task<IActionResult> Index(int? id, string subdomain)
            {
                 if (!string.IsNullOrWhiteSpace(subdomain))
                 {
                    if(subdomain=="admin")
                    return View("~/wwwrootadmin/index.cshtml");
                 }
                 return View("~/wwwroot/index.cshtml");
            }
        }
    

    Then wwwrootadmin has to be created with your files for the subdomain. Remember the order of route order matters inside the app.UseMvc()

    0 讨论(0)
  • 2021-01-06 09:53

    Today similar question is asked (not duplicate because versions are different).

    I can propose the same configuration to you, firstly, you must use nginx on your localserver to redirect or rewrite the url on localserver to specific sub-path, so no need to configure .net application to do redirection just configure the route areas.

    Mapping Subdomains to Areas in ASP.Net Core 3

    0 讨论(0)
  • 2021-01-06 09:55

    Michael Graf has a blog post about it.

    Basicly you need a custom router:

    public class AreaRouter : MvcRouteHandler, IRouter
    {
        public new async Task RouteAsync(RouteContext context)
        {
            string url = context.HttpContext.Request.Headers["HOST"]; 
            var splittedUrl = url.Split('.');
    
            if (splittedUrl.Length > 0 && splittedUrl[0] == "admin")
            {
                context.RouteData.Values.Add("area", "Admin");
            }
    
            await base.RouteAsync(context);
        }
    }
    

    And then register it.

    app.UseMvc(routes =>
    {
        routes.DefaultHandler = new AreaRouter();
        routes.MapRoute(name: "areaRoute",
            template: "{controller=Home}/{action=Index}");
    });
    

    On the other hand we have the IIS Rewrite module, or even a Middleware

    0 讨论(0)
  • 2021-01-06 09:56

    I tried the last solution and did not work for ASP.NET Core 1.1

    Microsoft has a nuget package named Rewrite, A middleware where you can rewrite or redirect some requests, but also there is a way to write a custom Rule, where you can capture the subdomain and add it to the request path:

    public class RewriteSubdomainRule : IRule
        {
            public void ApplyRule(RewriteContext context)
            {
                var request = context.HttpContext.Request;
                var host = request.Host.Host;
                // Check if the host is subdomain.domain.com or subdomain.localhost for debugging
                if (Regex.IsMatch(host, @"^[A-Za-z\d]+\.(?:[A-Za-z\d]+\.[A-Za-z\d]+|localhost)$"))
                {
                    string subdomain = host.Split('.')[0];
                    //modifying the request path to let the routing catch the subdomain
                    context.HttpContext.Request.Path = "/subdomain/" + subdomain + context.HttpContext.Request.Path;
                    context.Result = RuleResult.ContinueRules;
                    return;
                }
                context.Result = RuleResult.ContinueRules;
                return;
            }
        }
    

    On Startup.cs

    You have to add the middleware to use the custom rewrite rule:

     app.UseRewriter(new RewriteOptions().Add(new RewriteSubdomainRule())); 
    

    And after this lines I define a route that receives the subdomain added on the request path and assign it to the subdomain variable:

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
    
            routes.MapRoute(
                name: "subdomain",
                template: "subdomain/{subdomain}/{controller=Home}/{action=Index}/{id?}");
        });
    

    On the controller you can use it like this

    public async Task<IActionResult> Index(int? id, string subdomain)
    {
    }
    
    0 讨论(0)
提交回复
热议问题