Pat*_*ick 5 c# asp.net-mvc routes url-routing asp.net-mvc-routing
我有一个运行的MVC Web应用程序,www.domain.com我需要www.domain2.com为同一个Web应用程序的另一个域配置不同的URL绑定.
新域www.domain2.com必须返回特定的Controller Action View,如/Category/Cars:
routes.MapRoute(
name: "www.domain2.com",
url: "www.domain2.com",
defaults: new { controller = "Category", action = "Cars", id = UrlParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
如何在不更改URL的情况下实现此目的,以便访问者插入URL www.domain2.com并接收视图,www.domain.com/category/cars但网址仍然存在www.domain2.com?
编辑:
我尝试过这种方法,但它不起作用:
routes.MapRoute(
"Catchdomain2",
"{www.domain2.com}",
new { controller = "Category", action = "Cars" }
);
Run Code Online (Sandbox Code Playgroud)
域通常不是路由的一部分,这就是为什么您的示例不起作用的原因.要制作仅适用于特定域的路由,您必须自定义路由.
默认情况下,路由配置中的所有路由都可以在可以访问该网站的所有域上使用.
最简单的解决方案是创建自定义路由约束并使用它来控制特定URL匹配的域.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
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") }
);
}
}
Run Code Online (Sandbox Code Playgroud)
如果在Visual Studio中的新项目中启动它,您会注意到它显示错误.这是因为localhost:<port>不是已配置的域.但是,如果您导航到:
/?domain=www.domain.com
Run Code Online (Sandbox Code Playgroud)
您将看到主页.
这是因为仅对于调试版本,它允许您覆盖"本地"域名以进行测试.您可以 将本地IIS服务器配置为使用本地静态IP地址(添加到网卡)并添加本地主机文件条目以在本地测试它而不使用查询字符串参数.
请注意,在执行"发布"构建时,无法使用查询字符串参数进行测试,因为这会打开潜在的安全漏洞.
如果您使用URL:
/?domain=www.domain2.com
Run Code Online (Sandbox Code Playgroud)
它将运行CategoryController.Carsaction方法(如果存在).
请注意,由于Default航线涵盖范围广泛的URL,大部分网站将提供给双方 www.domain.com和www.domain2.com.例如,您可以在以下位置访问"关于"页面:
/Home/About?domain=www.domain.com
/Home/About?domain=www.domain2.com
Run Code Online (Sandbox Code Playgroud)
您可以使用IgnoreRoute扩展方法来阻止您不想要的URL(并且它接受路由约束,因此此解决方案也可以在那里工作).
如果您主要希望在域之间共享功能,则此解决方案将起作用.如果您希望在一个网站中拥有2个域,但让它们像单独的网站一样,如果您通过对区域使用上述路径约束为项目中的每个"网站" 使用区域,则会更容易管理路线.
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") }
);
}
}
Run Code Online (Sandbox Code Playgroud)
上述配置将使每个URL(即0,1,2或3段长)www.domain2.com路由到Domain2区域中的控制器.
在应用程序的默认操作中,确保 url 是第二个域之一,然后返回所需的方法。就像是:
public ActionResult Index()
{
if (Request.Url.Host.Equals("domain2"))
return AnotherAction();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
838 次 |
| 最近记录: |