0

我正在尝试做一个多租户应用程序,租户可以在其中获得自己的子域,例如

  • 租户1.mysite.com
  • 租户2.mysite.com

我试过使用自定义routedata,它只在第一页上有效,不知何故在 /login、/register 等其他页面上总是会抛出错误,而且它变得非常神秘。

我放弃并继续使用通配符 DNS 并让我的 HomeController 确定如何根据子域呈现视图

动作过滤器

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);
    }
}

家庭控制器

[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?

4

1 回答 1

1

我们通过制作自定义 ViewEngine 并使其了解应用程序的多租户来做了类似的事情...... ViewEngine 然后可以根据子域(在我们的例子中是物理的,但可能来自数据库)查找视图。

我们让 ViewEngine 继承自 RazorViewEngine,然后根据需要覆盖方法(FileExists、FindPartialView、FindView)

一旦我们有了一个自定义的 ViewEngine,我们就清除了其他的 ViewEngine,并在 global.asax 的 application_start 中注册了自定义的。

ViewEngines.Engines.Clear()
ViewEngines.Engines.Add(new CustomViewEngine()) 

我没有可以在自定义 ViewEngine 上分享的示例代码,但希望这会为您指明正确的方向。

于 2014-07-06T02:29:55.070 回答