我正在寻找一种将特定子域重新路由到asp.net核心中的Area的方法,因此实现就像
public class AreaRouter : MvcRouteHandler, IRouter
{
private readonly string[] _allowedSubdomains = { "Admin" };
private readonly IActionContextAccessor _actionContextAccessor;
private readonly IActionInvokerFactory _actionInvokerFactory;
private readonly IActionSelector _actionSelector;
private ILogger _logger;
private DiagnosticSource _diagnosticSource;
public AreaRouter(
IActionInvokerFactory actionInvokerFactory,
IActionSelector actionSelector,
DiagnosticSource diagnosticSource,
ILoggerFactory loggerFactory)
: this(actionInvokerFactory, actionSelector, diagnosticSource, loggerFactory, actionContextAccessor: null)
{
}
public AreaRouter(IActionInvokerFactory actionInvokerFactory, IActionSelector actionSelector, DiagnosticSource diagnosticSource,
ILoggerFactory loggerFactory, IActionContextAccessor actionContextAccessor)
: base(actionInvokerFactory, actionSelector, diagnosticSource,
loggerFactory, actionContextAccessor)
{
_actionContextAccessor = actionContextAccessor;
_actionInvokerFactory = actionInvokerFactory;
_actionSelector = actionSelector;
_diagnosticSource = diagnosticSource;
_logger = loggerFactory.CreateLogger<MvcRouteHandler>();
}
public new Task RouteAsync(RouteContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
string url = context.HttpContext.Request.Headers["HOST"];
string firstDomain = url.Split('.')[0];
string subDomain = char.ToUpper(firstDomain[0]) + firstDomain.Substring(1);
if (_allowedSubdomains.Contains(subDomain))
{
if (context.RouteData.Values.TryGetValue("area", out var area))
{
if (!area.Equals(subDomain.ToLowerInvariant()))
context.RouteData.Values.Add("area", subDomain);
}
else
{
context.RouteData.Values.Add("area", subDomain);
context.RouteData.Values["controller"] = "Dashboard";
}
}
var candidates = _actionSelector.SelectCandidates(context);
if (candidates == null || candidates.Count == 0)
{
return Task.CompletedTask;
}
var actionDescriptor = _actionSelector.SelectBestCandidate(context, candidates);
if (actionDescriptor == null)
{
return Task.CompletedTask;
}
context.Handler = (c) =>
{
var routeData = c.GetRouteData();
var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor);
if (_actionContextAccessor != null)
{
_actionContextAccessor.ActionContext = actionContext;
}
var invoker = _actionInvokerFactory.CreateInvoker(actionContext);
if (invoker == null)
{
throw new InvalidOperationException();
}
return invoker.InvokeAsync();
};
return Task.CompletedTask;
}
}
这与我的路由配置完美配合
app.UseMvc(routes =>
{
routes.DefaultHandler = areaRouter;
routes.MapRoute("areaRoute", "{area:exists}/{controller=Dashboard}/{action=Index}/{id?}");
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});
但是问题是当我生成链接时,它显示了URL上的区域。 admin.domain.com/admin
,因此如何仅使用像admin.domain.com
这样的子域部分来识别区域