Asp.net mvc 根据请求域绑定CSS文件?

Asp.net mvc 根据请求域绑定CSS文件?,asp.net-mvc,asp.net-mvc-3,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 3,Asp.net Mvc 4,我有一个多租户应用程序,我正试图根据任何传入请求的url确定控制绑定哪些CSS文件的最简单方法 我想我可以在RegisterBundles()中使用一些条件逻辑,将Url作为字符串,并相应地绑定: public static void RegisterBundles(BundleCollection bundles, string tenant = null) { if (tenant == "contoso"){ bundles.Add(new StyleBun

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

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

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

但我不知道如何将字符串传递到RegisterBundles,甚至不知道是否可能,也不知道正确的解决方案。这里的任何帮助都将非常棒。

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


另请参见SO问题。

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

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

视图中的示例代码:

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

正如您所说,在ViewBag中设置租户名称是有问题的,因为您必须按每个视图进行设置。解决此问题的一种方法是创建一个类似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());
    }
}
用法


捆绑包名称需要采用类似{bundle}-{tenant}的~/Content/css测试格式。但是你可以改变当然的格式。

我的英语不是很好,但是如果你的意思是当你运行页面中的任何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
    }
    
  • 转到routeConfig,将下面的地图添加到此文件(必须添加到此文件顶部):

  • 现在,创建一个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文件,如:


…“无论如何,每个租户绑定是一种更好的方法,因为在发布模式下绑定的所有内容(缓存、哈希等)bundle构造函数中的通配符支持使得在按文件夹分隔租户的情况下可以轻松地做到这一点——这实际上是两行代码。这很有趣。似乎每个视图我都必须这样做一次……是否有任何方法可以只对Layout.cshtml执行一次?是的,您可以创建类似于Styles.Render()的内容它考虑了从某处检索到的当前租户。
protected void Application_Start()
{
     RouteConfig.RegisterRoutes(RouteTable.Routes);

}
  routes.MapRoute(
        name: "Resource",
        url: "resource/{action}/{resourceName}",
        defaults: new { controller = "Resource" }
    );
public static class UrlHelperExtensions
{
    public static string Style(this UrlHelper urlHelper, string resourceName)
    {
    return urlHelper.Content(String.Format("~/resource/style/{0}", resourceName));
    }
 }