5

我有一个多租户应用程序,我正在尝试根据任何传入请求的 url 确定控制捆绑哪些 CSS 文件的最简单方法。

我想我可以在 RegisterBundles() 中有一些条件逻辑,它将 Url 作为字符串,并相应地捆绑:

public static void RegisterBundles(BundleCollection bundles, string tenant = null) {
     if (tenant == "contoso"){
           bundles.Add(new StyleBundle("~/contoso.css") 
     }
}

但我不知道如何将字符串传递到 RegisterBundles 中,即使可能,也不知道正确的解决方案。这里的任何帮助都会很棒。

4

3 回答 3

7

现在无法在 RegisterBundles 中执行此操作。每个请求动态生成捆绑内容将阻止 ASP.net 缓存缩小的 CSS(它缓存在 HttpContext.Cache 中)。

您可以在 RegisterBundles 中为每个租户创建一个捆绑包,然后在视图中选择适当的捆绑包。

视图中的示例代码:

@Styles.Render("~/Content/" + ViewBag.TenantName)

编辑:

正如您所说,在 ViewBag 中设置 TenantName 是有问题的,因为您必须针对每个视图执行此操作。解决这个问题的一种方法是创建一个像 Styles.Render() 这样的静态函数,它根据当前租户选择正确的包名称。

public static class TenantStyles
{
    public static IHtmlString Render(params string[] paths)
    {
        var tenantName = "test"; //get tenant name from where its currently stored
        var tenantExtension = "-" + tenantName;
        return Styles.Render(paths.Select(i => i + tenantExtension).ToArray());
    }
}

用法

@TenantStyles.Render("~/Content/css")

捆绑包名称需要采用 {bundle}-{tenant} 格式,例如 ~/Content/css-test。但是你当然可以改变格式。

于 2013-11-10T19:01:27.740 回答
1

我认为您正在寻求一种允许您动态控制 BundleCollection 的解决方案。据我所知,目前这是不可能的。捆绑包在应用程序启动期间配置/根据应用程序域进行配置。ASP.NET 的未来版本可能支持此功能,即使用 VirtualPathProvider。 这里有一些讨论。

另请参阅SO 问题。

于 2013-11-09T05:09:08.677 回答
0

我的英语不好,但如果你的意思是当你在页面中运行任何 URL 时需要处理哪个 CSS 文件加载,我可以在控制器中处理 css 文件。

  • 首先,创建一个控制器名称:ResourceController

    // CREATE PATH TO CSS FOLDER, I store in webconfig     <add key="PathToStyles" value="/Content/MyTheme/" />
    private static string _pathToStyles = ConfigurationManager.AppSettings["PathToStyles"];
    
    public void Script(string resourceName)
    {
        if (!String.IsNullOrEmpty(resourceName))
        {
            var pathToResource = Server.MapPath(Path.Combine(_pathToScripts, resourceName));
    
            TransmitFileWithHttpCachePolicy(pathToResource, ContentType.JavaScript.GetEnumDescription());
        }
    }
    
    public void Style(string resourceName)
    {
        if (!String.IsNullOrEmpty(resourceName))
        {
            var pathToResource = Server.MapPath(Path.Combine(_pathToStyles, resourceName));
    
            TransmitFileWithHttpCachePolicy(pathToResource, ContentType.Css.GetEnumDescription());
        }
    }
    
    private void TransmitFileWithHttpCachePolicy(string pathToResource, string contentType)
    {
        //DO WHAT YOU WANT HERE;
        Response.ContentType = contentType;
        Response.TransmitFile(pathToResource);
    }
    
    //You can handle css or js file...
    private enum ContentType
    {
        [EnumDescription("text/css")]
        Css,
        [EnumDescription("text/javascript")]
        JavaScript
    }
    
  • 在文件 Global.asax.cs 中,确保在应用程序启动方法中,包含路由配置

    protected void Application_Start()
    {
         RouteConfig.RegisterRoutes(RouteTable.Routes);
    
    }
    
  • 转到 routeConfig,将下面的地图添加到此文件(必须添加到此文件的顶部):

      routes.MapRoute(
            name: "Resource",
            url: "resource/{action}/{resourceName}",
            defaults: new { controller = "Resource" }
        );
    
  • 现在,创建一个 UrlHelperExtensions 类,与 webconfig 文件相同的路径

    public static class UrlHelperExtensions
    {
        public static string Style(this UrlHelper urlHelper, string resourceName)
        {
        return urlHelper.Content(String.Format("~/resource/style/{0}", resourceName));
        }
     }
    
  • 从现在开始,您可以在视图中定义 css 文件,例如:

..."<"link href="@Url.Style("yourcss.css")" rel="stylesheet" type="text/css" />

  • 希望这有帮助
于 2013-11-13T09:37:40.253 回答