区域和子域路由

时间:2016-11-09 17:07:25

标签: c# asp.net-core-mvc

我在ASP.NET核心应用程序中创建了管理区域并更新了我的路线:

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

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

我想在我的应用程序中实现子域路由,以便在我们输入URL admin.mysite.com时,我渲染我的管理区域(mysite.com/admin)。

我看到了很多ASP.NET MVC 5的例子,但我无法适应ASP.NET Core。

5 个答案:

答案 0 :(得分:1)

迈克尔格拉夫有a blog post关于它。

基本上你需要一个自定义路由器:

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

然后注册。

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

另一方面,我们有IIS Rewrite module,甚至是Middleware

答案 1 :(得分:1)

我尝试了最后一个解决方案,并且不适用于ASP.NET Core 1.1

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

您必须添加中间件才能使用自定义重写规则:

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

在这一行之后,我定义了一条路由,该路由接收在请求路径上添加的子域并将其分配给子域变量:

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

在控制器上你可以像这样使用它

public async Task<IActionResult> Index(int? id, string subdomain)
{
}

答案 2 :(得分:0)

很好的解决方案Sergio能够创建子域路由。 只需添加到您的解决方案并完成到域物理目录的子域路由。

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

然后必须使用子域的文件创建wwwrootadmin。请记住app.UseMvc()

中路由顺序的顺序

答案 3 :(得分:0)

今天提出了类似的问题(由于版本不同,因此不能重复)。

我可以向您提出相同的配置,首先,您必须在本地服务器上使用nginx将本地服务器上的url重定向或重写为特定的子路径,因此无需配置.net应用程序来进行重定向只需配置路由区域。

Mapping Subdomains to Areas in ASP.Net Core 3

答案 4 :(得分:0)

我终于在.Net Core 2.1中工作了

创建了一个新路由器

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

在Startup.cs中,将以下内容添加到ConfigureServices方法中:

services.AddSingleton<SubdomainAreaRouter>();

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