创建特定URL的路由,而无需使用MVC更改URL [英] Create Route for a specific URL without changing the URL with MVC

查看:56
本文介绍了创建特定URL的路由,而无需使用MVC更改URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行在 www.domain.com 上的MVC Web应用程序,并且我需要为另一个域 www配置另一个URL绑定。同一网络应用程序的domain2.com

I have a MVC Web Application that runs on www.domain.com and I need to configure a different URL binding for another domain www.domain2.com for the same web application.

新域 www.domain2.com 必须返回特定的控制器操作视图,例如 / Category / Cars

The new domain www.domain2.com will have to return a specific Controller Action View like /Category/Cars:

routes.MapRoute(
    name: "www.domain2.com",
    url: "www.domain2.com",
    defaults: new { controller = "Category", action = "Cars", id = UrlParameter.Optional }
);

如何在不更改URL的情况下实现此目的,因此访问者插入 www.domain2.com 并接收视图 www.domain.com/category/cars ,但网址仍为 www .domain2.com

How can I achieve this without changing the URL, so the visitor inserts the url www.domain2.com and receives the view www.domain.com/category/cars but the url remains www.domain2.com?

编辑:

我尝试了这种方法,但它不起作用:

I have tried this approach but it's not working:

routes.MapRoute(
    "Catchdomain2",
    "{www.domain2.com}",
    new { controller = "Category", action = "Cars" }
);


推荐答案

域通常不是路线的一部分,这就是为什么您的示例不起作用的原因。要使路由仅在特定域上起作用,您必须自定义路由。

Domains are normally not part of routes, which is why your examples don't work. To make routes that work only on specific domains you have to customize routing.


默认情况下,所有您的路由配置中的所有路由都将在可以访问该网站的所有域上提供。

最简单解决方案是创建一个 自定义路由约束 ,并使用它来控制特定URL将匹配的域。

The simplest solution for this is to create a custom route constraint and use it to control the domains that a specific URL will match.

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

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

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, 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.QueryString["domain"]; 
#else
                null;
#endif
            if (string.IsNullOrEmpty(domain))
                domain = httpContext.Request.Headers["HOST"];

            return domains.Contains(domain);
        }
    }



用法



Usage

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // This ignores Category/Cars for www.domain.com and www.foo.com
        routes.IgnoreRoute("Category/Cars", new { _ = new DomainConstraint("www.domain.com", "www.foo.com") });

        // Matches www.domain2.com/ and sends it to CategoryController.Cars
        routes.MapRoute(
            name: "HomePageDomain2",
            url: "",
            defaults: new { controller = "Category", action = "Cars" },
            constraints: new { _ = new DomainConstraint("www.domain2.com") }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },

            // This constraint allows the route to work either 
            // on "www.domain.com" or "www.domain2.com" (excluding any other domain)
            constraints: new { _ = new DomainConstraint("www.domain.com", "www.domain2.com") }
        );
    }
}

如果在Visual中的新项目中触发Studio,您会注意到它显示了一个错误。这是因为 localhost:< port> 不是配置的域。但是,如果您导航至:

If you fire this up in a new project in Visual Studio, you will notice it shows an error. This is because localhost:<port> is not a configured domain. However, if you navigate to:

/?domain=www.domain.com

您将看到主页。


这是因为仅用于调试版本,它允许您覆盖本地域名以进行测试。您可以 配置您的本地IIS服务器,以使用本地静态IP地址(添加到您的网卡)并添加本地主机文件条目,以在不查询的情况下在本地对其进行测试字符串参数

This is because for the debug build only, it allows you to override the "local" domain name for testing purposes. You can configure your local IIS server to use a local static IP address (added to your network card) and add a local hosts file entry to test it locally without the query string parameter.

请注意,在执行发布版本时,无法使用查询字符串参数进行测试,因为这样会打开潜在的安全漏洞。

Note that when doing a "Release" build, there is no way to test using a query string parameter, as that would open up a potential security vulnerability.

如果使用URL:

/?domain=www.domain2.com

它将运行 CategoryController.Cars 操作方法(如果存在)。

it will run the CategoryController.Cars action method (if one exists).

请注意,由于 Default 路由涵盖了广泛的URL,大部分站点都可以同时访问 www.domain.com www.domain2.com 。例如,您将能够同时在两个页面上找到关于页面:

Note that since the Default route covers a wide range of URLs, most of the site will be available to both www.domain.com and www.domain2.com. For example, you will be able to reach the About page both at:

/Home/About?domain=www.domain.com
/Home/About?domain=www.domain2.com

您可以使用 IgnoreRoute 扩展方法可以阻止不需要的URL(并且它接受路由约束,因此该解决方案也可以在其中使用)。

You can use the IgnoreRoute extension method to block URLs that you don't want (and it accepts route constraints, so this solution will work there, too).

如果您主要想在域之间共享功能,则此解决方案将起作用。如果您宁愿在一个网站中拥有2个域,但让它们像单独的网站一样工作,则使用区域

This solution will work if you largely want to share functionality between domains. If you would rather have 2 domains in one web site, but make them act like separate web sites, it would be easier to manage if you use an Area for each "web site" in your project by using the above route constraint for the Area routes.

public class Domain2AreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Domain2";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            name: "Domain2_default",
            url: "{controller}/{action}/{id}",
            defaults: new { action = "Index", id = UrlParameter.Optional }, 
            constraints: new { _ = DomainConstraint("www.domain2.com") }
        );
    }
}

以上配置将使每个URL (即长0、1、2或3个分段),将 www.domain2.com 路由到 Domain2 区域。

The above configuration would make every URL (that is 0, 1, 2, or 3 segments long) for www.domain2.com route to a controller in the Domain2 Area.

这篇关于创建特定URL的路由,而无需使用MVC更改URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆