C# 如何处理多租户ASP MVC站点的路径设置
我在一个需要支持基于主机的多租户的网站上工作,我已经解决了这一部分。我的问题是,我在CSS文件夹中为每个租户(1,2,3)设置了一个子文件夹 在tenant_X文件夹中,有自定义css文件用于为每个特定的租户设置Styling 我的想法是以某种方式创建一个虚拟位置(租户),该位置将映射到租户的文件夹,并且在_布局中只需要一行额外的coude。我对MVC不是很了解,到目前为止,我知道,我想我可以通过自定义路线来实现这一点。 这种方法的另一个原因是不允许租户用户看到还有其他租户。我必须排除让用户加载错误文件的可能性C# 如何处理多租户ASP MVC站点的路径设置,c#,css,asp.net-mvc,asp.net-mvc-4,C#,Css,Asp.net Mvc,Asp.net Mvc 4,我在一个需要支持基于主机的多租户的网站上工作,我已经解决了这一部分。我的问题是,我在CSS文件夹中为每个租户(1,2,3)设置了一个子文件夹 在tenant_X文件夹中,有自定义css文件用于为每个特定的租户设置Styling 我的想法是以某种方式创建一个虚拟位置(租户),该位置将映射到租户的文件夹,并且在_布局中只需要一行额外的coude。我对MVC不是很了解,到目前为止,我知道,我想我可以通过自定义路线来实现这一点。 这种方法的另一个原因是不允许租户用户看到还有其他租户。我必须排除让用户加载
这是正确的方法吗?你能提出更好的方法吗?只要在布局页面上添加一行,就可以实现这一点,可以从控制器获取一个文本/css格式的css文件 因此,假设当前租户ID在前端可用,您可以使用该ID在控制器上调用一个方法 例如,类似这样的事情:
@Styles.Render(string.Format("/CustomizationController/GetCssForTenant?tenantId={0}", loggedTeanant == null ? (int?) null : loggedTenant.Id))
现在用如下方法创建一个自定义控制器
public class CustomizationController : Controller
{
//this will cache cliente side the css file but if the duration expires
// or the tenantId changes it will be ask for the new file
[OutputCache(Duration = 43200, VaryByParam = "tenantId")]
public FileResult GetCssForTenant(int? tenantId)
{
var contentType = "text/css";
//if teanant id is null return empty css file
if(!tenantID.HasValue)
return new FileContentResult(new byte[0], contentType);
//load the real css file here <-
var result = ...
//---
//if having problems with the encoding use this ...
//System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
//var content = encoding.GetBytes(result);
//---
Response.ContentType = contentType;
return new FileContentResult(result, contentType);
//return new FileContentResult(content, contentType);
}
}
现在,如果发送1,页面的背景色应更改为黑色;如果发送2,页面的背景色应更改为粉红色。
您还可以在网络中看到,如果您使用相同的id请求2次,状态将为304,这意味着文件来自缓存。
如果更改id,则状态将为200,这是一个未缓存的响应
如果传递null,css文件将变为空,因此它将返回到默认css。结果很好,但最后我采用了另一种解决方案,可以同时解决多个问题。我已经覆盖了RazorViewEngine并插入了我自己的。这样我就完全控制了多个方面。但还是非常感谢。这是一个很好的解决方案
public class CustomizationController : Controller
{
//this will cache cliente side the css file but if the duration expires
// or the tenantId changes it will be ask for the new file
[OutputCache(Duration = 43200, VaryByParam = "tenantId")]
public FileResult GetCssForTenant(int? tenantId)
{
var contentType = "text/css";
//if teanant id is null return empty css file
if(!tenantID.HasValue)
return new FileContentResult(new byte[0], contentType);
//load the real css file here <-
var result = ...
//---
//if having problems with the encoding use this ...
//System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
//var content = encoding.GetBytes(result);
//---
Response.ContentType = contentType;
return new FileContentResult(result, contentType);
//return new FileContentResult(content, contentType);
}
}
public class CustomizationController : Controller
{
//this will cache cliente side the css file but if the duration expires
// or the tenantId changes it will be ask for the new file
[OutputCache(Duration = 43200, VaryByParam = "tenantId")]
public FileResult GetCssForTenant(int? tenantId)
{
var contentType = "text/css";
//if teanant id is null return empty css file
if(!tenantID.HasValue)
return new FileContentResult(new byte[0], contentType);
//load the real css file here <-
var result = Environment.NewLine;
if(tenantID = 1)
result "body{ background-color: black !important;}"
else
result "body{ background-color: pink !important;}"
result += Environment.NewLine;
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
var content = encoding.GetBytes(result);
Response.ContentType = contentType;
return new FileContentResult(result, contentType);
}
}
@Styles.Render(string.Format("/CustomizationController/GetCssForTenant?tenantId={0}", 1))