区域子域路由ASP.NET CORE

时间:2019-06-03 07:29:40

标签: c# asp.net-core routes

我正在寻找一种将特定子域重新路由到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这样的子域部分来识别区域

0 个答案:

没有答案