我正在尝试做一个多租户的应用程序,租户可以得到自己的子域,例如
- tenant1.mysite.com
- tenant2.mysite.com
我试过使用自定义routedata,它只在第一页上工作,不知何故在其他页面上,如/login,/register等,总是抛出错误,它变得非常神秘。
我放弃了,继续使用通配符DNS,让我的home控制器决定如何基于子域
呈现视图。ActionFilter
public class SubdomainTenancy : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string subdomain = filterContext.RequestContext.HttpContext.Request.Params["subdomain"]; // A subdomain specified as a query parameter takes precedence over the hostname.
if (subdomain == null)
{
string host = filterContext.RequestContext.HttpContext.Request.Headers["Host"];
int index = host.IndexOf('.');
if (index >= 0)
subdomain = host.Substring(0, index);
filterContext.Controller.ViewBag.Subdomain = subdomain;
}
base.OnActionExecuting(filterContext);
}
}
<<h2>家庭控制器/h2>[SubdomainTenancy]
[AllowAnonymous]
public class HomeController : BaseController
{
public ActionResult Index()
{
string subdomain = ViewBag.Subdomain;
if (subdomain != "www" && !string.IsNullOrEmpty(subdomain) )
{
var db = new tenantdb();
var store = db.GetBySubdomain(subdomain);
if (store == null)
{
return Redirect(HttpContext.Request.Url.AbsoluteUri.Replace(subdomain, "www"));
}
else //it's a valid tenant, let's see if there's a custom layout
{
//load custom view, (if any?)
}
}
return View();
}
}
所以现在的问题来了,当我尝试使用VirtualPathProvider加载基于子域的数据库视图,但我无法访问HttpContext,也许是由于生命周期?现在我卡住了,我也试过使用RazorEngine加载自定义视图(从数据库)
我应该做些什么来支持我的web应用程序上的多租户,将首先搜索数据库中的自定义视图并使用数据库中的视图进行渲染,否则如果没有,则退回到默认的/Home/Index.cshtml?
我们做了类似的事情,通过自定义ViewEngine并使其意识到应用程序的多租户…然后ViewEngine可以根据子域(在我们的例子中是物理的,但也可能来自数据库)查找视图。
我们让我们的ViewEngine从RazorViewEngine继承,然后我们根据需要重写方法(FileExists, FindPartialView, FindView)
一旦我们有了一个自定义的ViewEngine,然后我们就清除了其他的ViewEngine,并在global.asax的application_start中注册了自定义的ViewEngine。
ViewEngines.Engines.Clear()
ViewEngines.Engines.Add(new CustomViewEngine())
我没有示例代码可以分享自定义ViewEngine,但希望这将指向正确的方向。