我有一个在www.domain.com
上运行的MVC Web应用程序,我需要为同一个Web应用程序的另一个域www.domain2.com
配置不同的URL绑定。
新域www.domain2.com
必须返回特定的控制器操作视图,例如/Category/Cars
:
routes.MapRoute(
name: "www.domain2.com",
url: "www.domain2.com",
defaults: new { controller = "Category", action = "Cars", id = UrlParameter.Optional }
);
如何在不更改网址的情况下实现此目的,以便访问者插入网址www.domain2.com
并接收视图www.domain.com/category/cars
,但网址仍为www.domain2.com
?
编辑:
我尝试过这种方法,但它不起作用:
routes.MapRoute(
"Catchdomain2",
"{www.domain2.com}",
new { controller = "Category", action = "Cars" }
);
答案 0 :(得分:6)
域通常不部分路由,这就是您的示例不起作用的原因。要制作仅在特定域上工作的路线,您必须自定义路由。
默认情况下,路线配置中的所有路线都可以在可以访问该网站的所有域上使用。
最简单的解决方案是创建custom route constraint并使用它来控制特定网址匹配的域。
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>
不是已配置的域。但是,如果您导航到:
/?domain=www.domain.com
您将看到主页。
这是因为仅针对调试版本,它允许您覆盖“本地”域名以进行测试。您可以 configure your local IIS server使用本地静态IP地址(添加到您的网卡)并添加本地主机文件条目以在本地测试,而不使用查询字符串参数
请注意,在执行“发布”构建时,无法使用查询字符串参数进行测试,因为这会打开潜在的安全漏洞。
如果您使用网址:
/?domain=www.domain2.com
它将运行CategoryController.Cars
操作方法(如果存在)。
请注意,由于Default
路线涵盖了广泛的网址,因此 www.domain.com
和www.domain2.com
都可以使用该网站的大部分内容。例如,您可以在以下位置访问“关于”页面:
/Home/About?domain=www.domain.com
/Home/About?domain=www.domain2.com
您可以使用您不想要的IgnoreRoute
extension method 阻止网址(并且它接受路由限制,因此此解决方案也可以在那里使用)。
如果主要希望在域之间共享功能,则此解决方案将起作用。如果您希望在一个网站中拥有2个域,但是让它们像单独的网站一样,如果您使用上述路线为项目中的每个“网站”使用Area,则会更容易管理区域路线的约束。
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") }
);
}
}
以上配置将{em>每个URL (即0,1,2或3段长)用于www.domain2.com
路由到Domain2
区域中的控制器。
答案 1 :(得分:0)
在应用程序的默认操作中,确保url是第二个域之一,然后返回需要的方法。类似的东西:
public ActionResult Index()
{
if (Request.Url.Host.Equals("domain2"))
return AnotherAction();
}
答案 2 :(得分:0)
同意上面的答案。
如果你想要更漂亮的实现 - 尝试动作过滤器。 操作示例过滤了there的使用情况。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (SomeControllerBase) filterContext.Controller;
filterContext.Result = controller.RedirectToAction("index", "home");
}
从there获取动作过滤器内的网址的示例。
var url = filterContext.HttpContext.Request.Url;
把事情放在一起,玩得开心:)