简体   繁体   English

区域和子域路由

[英]Area and subdomain routing

I created Admin Area inside my ASP.NET Core application and updated my routes like that:我在 ASP.NET Core 应用程序中创建了管理区域,并像这样更新了我的路由:

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

    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}");
});

I would like to implement subdomain routing inside my application in order to when we type URL admin.mysite.com, I render my Admin area (mysite.com/admin).我想在我的应用程序中实现子域路由,以便在我们输入 URL admin.mysite.com 时呈现我的管理区域 (mysite.com/admin)。

I saw many examples for ASP.NET MVC 5, but I have not been able to adapt for ASP.NET Core.看了很多ASP.NET MVC 5的例子,但是一直没能适配ASP.NET Core。

Michael Graf has a blog post about it. Michael Graf 有一篇关于它的博客文章

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另一方面,我们有IIS 重写模块,甚至是中间件

I tried the last solution and did not work for ASP.NET Core 1.1我尝试了最后一个解决方案,但不适用于 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: Microsoft 有一个名为 Rewrite 的 nuget 包,一个中间件,您可以在其中重写或重定向某些请求,但也有一种方法可以编写自定义规则,您可以在其中捕获子域并将其添加到请求路径中:

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在启动.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)
{
}

Good solution Sergio was able to create the subdomain routing.好的解决方案 Sergio 能够创建子域路由。 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.然后必须使用子域的文件创建 wwwrootadmin。 Remember the order of route order matters inside the app.UseMvc()记住 app.UseMvc() 中的路由顺序很重要

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.我可以给你提出相同的配置,首先你必须在你的localserver上使用nginx来重定向或重写localserver上的url到特定的子路径,所以不需要配置.net应用程序来做重定向,只需配置路由区域。

Mapping Subdomains to Areas in ASP.Net Core 3 将子域映射到 ASP.Net Core 3 中的区域

I finally got this working in .Net Core 2.1我终于在 .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:在 Startup.cs 中,将以下内容添加到 ConfigureServices 方法中:

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:在 Startup.cs 中,将新路由器传入 Configure 方法并更新 UseMvc 逻辑以使用新路由器:

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?}");
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM