I created Admin Area inside my ASP.NET Core application and updated my routes like that:
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).
I saw many examples for ASP.NET MVC 5, but I have not been able to adapt for ASP.NET Core.
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)
{
}
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
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()
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