Mvc5多租户和自定义视图



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

  • 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,但希望这将指向正确的方向。

相关内容

  • 没有找到相关文章

最新更新