Different domain in the same app ASP.NET Core 2.0

纵饮孤独 提交于 2019-12-18 11:35:05

问题


I have ASP.NET Core 2.0 app hosted in Azure web app.

This app have configured domain domainA.com.

I have one route in my app for example domainA.com/route. Now I want to pin other domain only to this route for example domainB.com.

What is the best way to do this?


回答1:


One way to accomplish this is to make a custom route constraint to specify which routes function for each domain name.

DomainConstraint

    public class DomainConstraint : IRouteConstraint
    {
        private readonly string[] domains;

        public DomainConstraint(params string[] domains)
        {
            this.domains = domains ?? throw new ArgumentNullException(nameof(domains));
        }

        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            string domain =
#if DEBUG
                // A domain specified as a query parameter takes precedence 
                // over the hostname (in debug compile only).
                // This allows for testing without configuring IIS with a 
                // static IP or editing the local hosts file.
                httpContext.Request.Query["domain"];
#else
                null;
#endif
            if (string.IsNullOrEmpty(domain))
                domain = httpContext.Request.Host.Host;

            return domains.Contains(domain);
        }
    }

Usage

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "DomainA",
        template: "route",
        defaults: new { controller = "DomainA", action = "Route" },
        constraints: new { _ = new DomainConstraint("domaina.com") });

    routes.MapRoute(
        name: "DomainB",
        template: "route",
        defaults: new { controller = "DomainB", action = "Route" },
        constraints: new { _ = new DomainConstraint("domainb.com") });

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

Note that if you fire this up in Visual Studio it won't work with the standard configuration. To allow for easy debugging without changing the configuration, you can specify the URL with the domain as a query string parameter:

/route?domain=domaina.com

This is just so you don't have to reconfigure IIS and your local hosts file to debug (although you still can if you prefer that way). During a Release build this feature is removed so it will only work with the actual domain name in production.

Since routes respond to all domain names by default, it only makes sense to do it this way if you have a large amount of functionality that is shared between domains. If not, it is better to setup separate areas for each domain:

routes.MapRoute(
    name: "DomainA",
    template: "{controller=Home}/{action=Index}/{id?}",
    defaults: new { area = "DomainA" },
    constraints: new { _ = new DomainConstraint("domaina.com") }
);

routes.MapRoute(
    name: "DomainA",
    template: "{controller=Home}/{action=Index}/{id?}",
    defaults: new { area = "DomainB" },
    constraints: new { _ = new DomainConstraint("domainb.com") }
);



回答2:


For .net Core MVC, you can create a new IRouteConstraint and a RouteAttribute

=> IRouteConstraint.cs

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Microsoft.AspNetCore.Routing
{
    public class ConstraintHost : IRouteConstraint
    {

        public string _value { get; private set; }
        public ConstraintHost(string value)
        {
            _value = value;
        }

        public bool Match(HttpContext httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            string hostURL = httpContext.Request.Host.ToString();
            if (hostURL == _value)
            {
                return true;
            }
            //}
            return false;
            //return hostURL.IndexOf(_value, StringComparison.OrdinalIgnoreCase) >= 0;
        }

        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            throw new NotImplementedException();
        }
    }
    public class ConstraintHostRouteAttribute : RouteAttribute
    {
        public ConstraintHostRouteAttribute(string template, string sitePermitted)
            : base(template)
        {
            SitePermitted = sitePermitted;
        }

        public RouteValueDictionary Constraints
        {
            get
            {
                var constraints = new RouteValueDictionary();
                constraints.Add("host", new ConstraintHost(SitePermitted));
                return constraints;
            }
        }

        public string SitePermitted
        {
            get;
            private set;
        }
    }
} 

And in your Controller can use it like that:

    [ConstraintHostRoute("myroute1/xxx", "domaina.com")]
    [ConstraintHostRoute("myroute2/yyy", "domainb.com")]
    public async Task<ActionResult> MyController()
    {
      return View();
    }


来源:https://stackoverflow.com/questions/49378474/different-domain-in-the-same-app-asp-net-core-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!