如何根据主机名加载正确的控制器
How to load the correct controller based on host name
我正在寻找有关如何实现以下目标的建议。
我有一个 MVC5 .NET 网络应用程序。在这个应用程序中,我创建了一个基本控制器,这个控制器是许多子控制器的父控制器。每个子控制器都有自己的一组视图,它们有自己的一组 sass 和 JavaScript 文件。我需要做的是根据主机 URL 加载正确的控制器,而不是在 URL 中显示控制器名称,例如www.host1.co.uk 将加载 controller1,而 www.host2.co.uk 将加载 controller2,当站点为 运行 时,URL 需要看起来像这样 www.host1.co。 uk/Index 不是 www.host1.co.uk/controller1/Index
我正在做的另一件事是使用 Ninject 将我们所有的业务逻辑服务注入到控制器中,我想继续这样做。
任何帮助将不胜感激
下面是控制器结构的例子,供参考
public abstract class BaseController : Controller
{
private readonly IService1 _service1;
private readonly IService2 _service2;
protected BaseController(IService1 service1, IService2 service2)
{
_service1 = service1;
_service2 = service2;
}
// GET: Base
public virtual ActionResult Index()
{
return View();
}
[HttpPost]
public virtual ActionResult Index(IndexViewModel model)
{
//DoSomething
return View();
}
}
public class HostController1 : BaseController
{
public HostController1(IService1 service1, IService2 service2)
: base(service1, service2)
{
}
}
您可以实施验证主机名的自定义路由约束
namespace Infrastructure.CustomRouteConstraint
{
public class HostNameConstraint : IRouteConstraint
{
private string requiredHostName;
public HostNameConstraint(string hostName)
{
requiredHostName = hostName;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
// get the host name from Url.Authority property and compares it with the one obtained from the route
return httpContext.Request.Url.Authority.Contains(requiredHostName);
}
}
}
然后,在您的 RouteConfig.cs 顶部,您可以创建两个指定这些主机名的新路由:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Host1Route", "{action}",
new { controller = "One", action = "Index" },
new { customConstraint = new HostNameConstraint("www.host1.co.uk") });
routes.MapRoute("Host2Route", "{action}",
new { controller = "Two", action = "Index" },
new { customConstraint = new HostNameConstraint("www.host2.co.uk") });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
现在,来自主机 "www.host1.co.uk" 的每个请求都将使用 "OneController" 的操作方法进行处理,而来自 "www.host2.co.uk" 的每个请求将使用 "TwoController" 的操作方法进行处理](并且 URL 中没有控制器名称,如 "www.host2.co.uk/Test")
我正在寻找有关如何实现以下目标的建议。
我有一个 MVC5 .NET 网络应用程序。在这个应用程序中,我创建了一个基本控制器,这个控制器是许多子控制器的父控制器。每个子控制器都有自己的一组视图,它们有自己的一组 sass 和 JavaScript 文件。我需要做的是根据主机 URL 加载正确的控制器,而不是在 URL 中显示控制器名称,例如www.host1.co.uk 将加载 controller1,而 www.host2.co.uk 将加载 controller2,当站点为 运行 时,URL 需要看起来像这样 www.host1.co。 uk/Index 不是 www.host1.co.uk/controller1/Index
我正在做的另一件事是使用 Ninject 将我们所有的业务逻辑服务注入到控制器中,我想继续这样做。
任何帮助将不胜感激
下面是控制器结构的例子,供参考
public abstract class BaseController : Controller
{
private readonly IService1 _service1;
private readonly IService2 _service2;
protected BaseController(IService1 service1, IService2 service2)
{
_service1 = service1;
_service2 = service2;
}
// GET: Base
public virtual ActionResult Index()
{
return View();
}
[HttpPost]
public virtual ActionResult Index(IndexViewModel model)
{
//DoSomething
return View();
}
}
public class HostController1 : BaseController
{
public HostController1(IService1 service1, IService2 service2)
: base(service1, service2)
{
}
}
您可以实施验证主机名的自定义路由约束
namespace Infrastructure.CustomRouteConstraint
{
public class HostNameConstraint : IRouteConstraint
{
private string requiredHostName;
public HostNameConstraint(string hostName)
{
requiredHostName = hostName;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
// get the host name from Url.Authority property and compares it with the one obtained from the route
return httpContext.Request.Url.Authority.Contains(requiredHostName);
}
}
}
然后,在您的 RouteConfig.cs 顶部,您可以创建两个指定这些主机名的新路由:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Host1Route", "{action}",
new { controller = "One", action = "Index" },
new { customConstraint = new HostNameConstraint("www.host1.co.uk") });
routes.MapRoute("Host2Route", "{action}",
new { controller = "Two", action = "Index" },
new { customConstraint = new HostNameConstraint("www.host2.co.uk") });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
现在,来自主机 "www.host1.co.uk" 的每个请求都将使用 "OneController" 的操作方法进行处理,而来自 "www.host2.co.uk" 的每个请求将使用 "TwoController" 的操作方法进行处理](并且 URL 中没有控制器名称,如 "www.host2.co.uk/Test")