想象一个绑定了许多域的站点。fe product1.com, product2.com, ...
当product23 出现故障时,想法是让“landingpagecontroller”为product23.com 提供所有请求。
这个想法是写一个 ActionFilter 来完成这个:
public class Landingpage : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var DnsSafeHost = filterContext.HttpContext.Request.Url.DnsSafeHost;
if (DnsSafeHost.NeedsLandingpage())
{
//Do actual redirecting
}
}
}
NeedsLandingpage() 返回一个布尔值。如果需要登陆页面控制器服务,则为真。情报将在数据库中找到。
我已经添加了到登录页面控制器的路由。
routes.MapRoute(
name: "Ladingpage",
url: "Landingpage/{id}/{*dummy}",
defaults: new { controller = "LandingPage", action = "Index" }
);
关于如何从 actionfilter 更改路由设置以触发上述路由或实现目标的更好解决方案的任何提示。
********** 更新 ************
鉴于大家的意见,我想出了以下可行的解决方案,但我对它并不是 100% 满意。因此,欢迎提供更好的解决方案。
我创建了以下 IActionFilter 并将其注册为全局。
public class Landingpage : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var DnsSafeHost = filterContext.HttpContext.Request.Url.DnsSafeHost;
var _LandingPage = LandingPage(DnsSafeHost);
if (_LandingPage != null)
{
if ((String)filterContext.RouteData.Values["controller"] != "Landingpage")
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Landingpage", action = "Index", id = _LandingPage }));
filterContext.Result.ExecuteResult(filterContext.Controller.ControllerContext);
}
}
}
private String LandingPage(String DnsSafeHost)
{
if (DnsSafeHost.Contains("<domain to look for>".ToLower())) return "<viewname>";
if (DnsSafeHost.Contains("<domain to look for>".ToLower())) return "<viewname>";
if (DnsSafeHost.Contains("<domain to look for>".ToLower())) return "<viewname>";
return null;
}
}
我不喜欢该解决方案的是检查 (String)filterContext.RouteData.Values["controller"]
这是需要的,否则您会陷入循环,因为。
浏览器 -> 路由 -> 过滤器 -> 重定向 -> 路由 -> 过滤器...
我认为一个可能的解决方案是在 Application_BeginRequest (global.asax) 中做一些事情。但我没有找到“重写”请求的方法。因为如果这可能,流程将是:浏览器 -> BeginRequest -> RewriteRequest -> 路由 -> 控制器。
我猜,如果您遵循最佳实践,那么在 vNext 中,下站点似乎将不再起作用。
过滤器配置文件
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new Landingpage());
}
}
所有“登陆页面”调用都被重定向到 LandingPageController。对 ViewEngine 的调用用于检查从 actionfilter 传递的视图名称是否存在,如果不使用默认值。
public class LandingpageController : Controller
{
public ActionResult Index(string id)
{
if (id == null) return View();
if (ViewEngines.Engines.FindView(ControllerContext, id, null).View == null) return View();
ViewBag.Title = id;
return View(id);
}
}
视图示例。
@{
Layout = "_Index_layout.cshtml";
}
<div class="domainname">Landingpage</div>
为了给它一个不同于普通页面的“特殊”布局(没有菜单),我为此页面添加了一个自定义布局。
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<style>
--- add some styling here ---
</style>
</head>
<body>
@RenderBody()
</body>
</html>