从MVC5或Web API 2控制器操作返回生成的CSS
在我们的多租户应用程序中,我们需要自定义每个租户使用的样式 我们目前计划在客户机上以以下方式使用较少的和变量:从MVC5或Web API 2控制器操作返回生成的CSS,css,asp.net-mvc,less,asp.net-web-api2,Css,Asp.net Mvc,Less,Asp.net Web Api2,在我们的多租户应用程序中,我们需要自定义每个租户使用的样式 我们目前计划在客户机上以以下方式使用较少的和变量: 从服务器下载依赖较少的文件 调用web服务以获取配置对象 定义了变量的有效LESS的表单字符串 使用less.js编译器根据这些变量和步骤1中固定的less文件编译less 这种方法有许多缺点: 客户可能表现不好 一些浏览器在less.js上有问题 编译需要时间 相反,我们希望在服务器上完成这项工作,因此粗略地说,这是在服务器上进行的: 客户端请求下载一个大的编译样式表-GET c
less.js
编译器根据这些变量和步骤1中固定的less文件编译less- 客户可能表现不好
- 一些浏览器在
less.js上有问题
- 编译需要时间
GET content/styles/{tenantName}.css
tenantName
服务器获取配置string.Format
或更复杂的东西) var themeStyles = new CustomStyleBundle("~bundles/theme/tenant").Include("~/Content/theme.less");
themeStyles.Builder = new ThemeBuilder();
BundleTable.Bundles.Add(themeStyles);
如果您不这样做,并且租户像我们的情况一样灵活,那么为您的主题添加以下控制器操作
[Route("bundles/theme/{id}")]
public ContentResult Theme(string id)
{
var tenantThemePath = string.Format("~/bundles/theme/{0}", id);
// Check that bundle has not already been added.
if (BundleTable.Bundles.All(x => x.Path != tenantThemePath))
{
var themeStyles = new CustomStyleBundle(tenantThemePath ).Include("~/Content/theme.less");
themeStyles.Builder = new ThemeBuilder();
BundleTable.Bundles.Add(themeStyles);
}
var context = new BundleContext(HttpContext, BundleTable.Bundles, institutionPath);
var response = BundleTable.Bundles.GetBundleFor(tenantThemePath).GenerateBundleResponse(context);
Response.Cache.SetCacheability(response.Cacheability);
return Content(response.Content, response.ContentType);
}
BundleTransformer的ThemeBuilder实现
public class ThemeBuilder : IBundleBuilder
{
public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
{
var lessTranslator = bundle.Transforms.OfType<StyleTransformer>()
.Where(x => x != null)
.Select(x => x.Translators.OfType<LessTranslator>().FirstOrDefault())
.FirstOrDefault();
if (lessTranslator == null)
{
return string.Empty;
}
lessTranslator.GlobalVariables = GetThemeVariables();
return string.Empty;
}
private string GetThemeVariables()
{
// Simplified for brevity
// This will be translated to less variables by the BundleTransformer
// themeColour should correspond to a variable name in your less file.
return string.Format("themeColour={0}", themeColour);
}
}
public类ThemeBuilder:IBundleBuilder
{
公共字符串BuildBundleContent(捆绑包、BundleContext上下文、IEnumerable文件)
{
var lestranslator=bundle.Transforms.OfType()
.其中(x=>x!=null)
.Select(x=>x.Translators.OfType().FirstOrDefault())
.FirstOrDefault();
if(lessTranslator==null)
{
返回字符串。空;
}
lessTranslator.GlobalVariables=GetThemeVariables();
返回字符串。空;
}
私有字符串GetThemeVariables()
{
//为简洁起见简化
//BundleTransformer会将其转换为更少的变量
//颜色应与less文件中的变量名相对应。
返回string.Format(“themeColour={0}”,themeColour);
}
}
我们将这些变量隐藏在HttpContext存储中,这样我们就可以使用GetThemeVariables方法中的扩展方法将它们提取出来
我希望这有帮助
更新
我扩展了我的原始答案,并创建了一种更可重用的包含主题的方式
演示站点:
GitHub repo here:您是否已经将所有less文件预先编译为css,那么这只是提供正确的css文件的一种情况。不,因为在编译时不知道租户。