問題描述
我有一個在 www.domain.com
上運行的 MVC Web 應用程序,我需要為另一個域 www.domain2.com
配置不同的 URL 綁定相同的網絡應用程序.
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 的情況下實現這一點,因此訪問者插入 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.
默認情況下,您的路由配置中的所有路由都將在可以訪問該網站的所有域上可用.
By default, all of the routes in your route configuration will be available on all domains that can reach the web site.
最簡單的解決方案是創建一個 自定義路由約束 并使用它來控制特定 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);
}
}
用法
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 地址(添加到您的網卡)并添加本地 hosts 文件條目以在本地測試它無需查詢字符串參數.
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.
請注意,在執行Release"時,構建時,無法使用查詢字符串參數進行測試,因為這會帶來潛在的安全漏洞.
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.
如果您使用網址:
/?domain=www.domain2.com
它將運行 CategoryController.Cars
操作方法(如果存在).
it will run the CategoryController.Cars
action method (if one exists).
請注意,由于 Default
路由涵蓋了范圍廣泛的 URL,因此大部分站點都可用于 both 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
擴展方法 到 block 您不想要的 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") }
);
}
}
上述配置將使 www.domain2.com
的 每個 URL(即 0、1、2 或 3 段長)路由到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.
這篇關于在不使用 MVC 更改 URL 的情況下為特定 URL 創建路由的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!