2013-02-12 117 views
5

我有IIS上的虛擬目錄,其中包含所有的JavaScript和CSS文件。是否可以使用Bundles將這些文件包含到ASP.NET MVC應用程序中。ASP.NET MVC與絕對路徑捆綁

我已經嘗試過這樣的事情:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include("/public/javascript/jquery-{version}.js")); 

,但得到的錯誤:

Only application relative URLs (~/url) are allowed.:

/公/ JavaScript是在IIS虛擬目錄。

+0

您使用的是MVC3還是4?你爲什麼要標籤兩次? – 2013-02-12 15:00:02

+0

我也在找這個。但是我擔心MVC bundle不支持除〜/ public/javascript/foo.js之類的應用程序相關路徑 – oruchreis 2013-03-05 12:43:03

回答

4

其實Bundle類不支持絕對路徑。我已經打開了a feature request here.

我已經用自定義的VirtualPathProvider和控制器解決了這個問題。但這是非常脆弱的實施。您可以根據需要進行修改。

public class ModuleScriptProvider : VirtualPathProvider 
{ 
    public static IBundleModule GetModulePath(string moduleName) 
    { 
     //return the absolute or relative path. 
    } 

    public static void ParseVirtualPath(string virtualPath, out string moduleName, out string path) 
    { 
     var parts = virtualPath.Replace("~/", "").Split('/').Where(p => !string.IsNullOrEmpty(p)).Skip(1).ToList(); 
     if (parts.Count < 2 || !virtualPath.EndsWith(".js")) 
      throw new FileNotFoundException("Script file doesn't found in the module script directory", virtualPath); 
     moduleName = parts.First(); // ~/ModuleScript/ModuleName/.... 
     path = string.Join(@"\", parts.Skip(1)); 
    } 

    public static string MapPathMethod(string virtualPath) 
    { 
     if (IsModuleScriptPath(virtualPath)) 
     { 
      string moduleName; 
      string path; 
      ParseVirtualPath(virtualPath, out moduleName, out path); 
      var moduleDir = GetModulePath(moduleName); //absolute path 
      if (!moduleDir.EndsWith(@"\")) 
       moduleDir += @"\"; 
      return moduleDir + path; 
     } 
     return HttpContext.Current.Server.MapPath(virtualPath); 
    } 

    public static bool IsModuleScriptPath(string virtualPath) 
    { 
     String checkPath = VirtualPathUtility.ToAppRelative(virtualPath); 

     return checkPath.StartsWith("~/ModuleScript/", StringComparison.InvariantCultureIgnoreCase); 
    } 

    public override bool FileExists(string virtualPath) 
    { 
     return (IsModuleScriptPath(virtualPath) || base.FileExists(virtualPath)); 
    } 
    public override VirtualFile GetFile(string virtualPath) 
    { 
     if (IsModuleScriptPath(virtualPath)) 
      return new ModuleScriptVirtualFile(virtualPath); 
     return base.GetFile(virtualPath); 
    } 

    public override CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart) 
    { 
     if (IsModuleScriptPath(virtualPath)) 
     { 
      string moduleName; 
      string path; 
      ParseVirtualPath(virtualPath, out moduleName, out path); 
      var bundleModulePath = GetModulePath(moduleName); 
      return new CacheDependency(bundleModulePath); 
     } 

     return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); 
    } 
    public override string CombineVirtualPaths(string basePath, string relativePath) 
    { 
     return base.CombineVirtualPaths(basePath, relativePath); 
    } 
} 

class ModuleScriptVirtualFile : VirtualFile 
{ 
    private readonly string _path; 
    private readonly string _moduleName; 
    public ModuleScriptVirtualFile(string virtualPath) 
     : base(virtualPath) 
    { 
     ModuleScriptProvider.ParseVirtualPath(virtualPath, out _moduleName, out _path); 
    } 
    public override Stream Open() 
    { 
     var moduleDir = ModuleScriptProvider.GetModulePath(_moduleName); 
     if (!moduleDir.EndsWith(@"\")) 
      moduleDir += @"\"; 

     return new FileStream(moduleDir + _path, FileMode.Open); 
    } 
} 

控制器:

public class ModuleScriptController : Controller 
{ 
    public FileStreamResult GetFile(string path) 
    { 
     return new FileStreamResult(new ModuleScriptProvider().GetFile("~/ModuleScript/" + path).Open(), "text/javascript"); 
    } 
} 

在Global.asax中Application_Start方法中:

HostingEnvironment.RegisterVirtualPathProvider(new ModuleScriptProvider()); 
BundleTable.EnableOptimizations = true; 
BundleTable.MapPathMethod = ModuleScriptProvider.MapPathMethod; 

神速度。