Вопрос

I'm using SignalR, which maps to asp.net application on virtual path "~/signalr". SignalR dynamically creates javascript proxy hubs on app start with virtual path "~/signalr/hubs".

So the url "[http://myapp]/signalr/hubs" is where dynamic javascript content is. How can I add this virtual path to Asp.Net Web Optimization Bundling?

Asp.Net Web Optimization Framework starting from 1.1 supports VirtuPathProvider's: ASP.NET bundling/minification: including dynamically generated Javascript

Actually I don't understand how to use these VPP's. Could somebody explain in details or better give an example?

Это было полезно?

Решение

Integration of dynamic content into the bundling process requires the following steps:

  1. Writing the logic that requests / builds the required content. For SignalR you could use this code snippet:

    public static string GetSignalRContent()
    {
        var resolver = new DefaultHubManager(new DefaultDependencyResolver());
        var proxy = new DefaultJavaScriptProxyGenerator(resolver, new NullJavaScriptMinifier());
        return proxy.GenerateProxy("/signalr");
    }
    
  2. Implement a virtual path provider that wraps the existing one and intercept all virtual paths that should deliver the dynamic content (just "~/signalr/hubs" in your case).

    public class CustomVirtualPathProvider : VirtualPathProvider
    {
        public CustomActionVirtualPathProvider(VirtualPathProvider virtualPathProvider)
        {
            // Wrap an existing virtual path provider
            VirtualPathProvider = virtualPathProvider;
        }
    
        protected VirtualPathProvider VirtualPathProvider { get; set; }
    
        public override string CombineVirtualPaths(string basePath, string relativePath)
        {
            return VirtualPathProvider.CombineVirtualPaths(basePath, relativePath);
        }
    
        public override bool DirectoryExists(string virtualDir)
        {
            return VirtualPathProvider.DirectoryExists(virtualDir);
        }
    
        public override bool FileExists(string virtualPath)
        {
            if (virtualPath == "~/signalr/hubs")
            {
                return true;
            }
    
            return VirtualPathProvider.FileExists(virtualPath);
        }
    
        public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            // BaseClass can't create a CacheDependency for your content, remove it
            // You could also add your own CacheDependency and aggregate it with the base dependency
            List<string> virtualPathDependenciesCopy = virtualPathDependencies.Cast<string>().ToList();
            virtualPathDependenciesCopy.Remove("~/signalr/hubs");
    
            return VirtualPathProvider.GetCacheDependency(virtualPath, virtualPathDependenciesCopy, utcStart);
        }
    
        public override string GetCacheKey(string virtualPath)
        {
            return VirtualPathProvider.GetCacheKey(virtualPath);
        }
    
        public override VirtualDirectory GetDirectory(string virtualDir)
        {
            return VirtualPathProvider.GetDirectory(virtualDir);
        }
    
        public override VirtualFile GetFile(string virtualPath)
        {
            if (virtualPath == "~/signalr/hubs")
            {
                return new CustomVirtualFile(virtualPath,
                    new MemoryStream(Encoding.Default.GetBytes(GetSignalRContent())));
            }
    
            return VirtualPathProvider.GetFile(virtualPath);
        }
    
        public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
        {
            return VirtualPathProvider.GetFileHash(virtualPath, virtualPathDependencies);
        }
    
        public override object InitializeLifetimeService()
        {
            return VirtualPathProvider.InitializeLifetimeService();
        }
    }
    
    public class CustomVirtualFile : VirtualFile
    {
        public CustomVirtualFile (string virtualPath, Stream stream)
            : base(virtualPath)
        {
            Stream = stream;
        }
    
        public Stream Stream { get; private set; }
    
        public override Stream Open()
        {
             return Stream;
        }
    }
    
  3. Register your virtual path provider:

    public static void RegisterBundles(BundleCollection bundles)
    {
        // Set the virtual path provider
        BundleTable.VirtualPathProvider =
            new CustomVirtualPathProvider(BundleTable.VirtualPathProvider);
    
        Bundle include = new Bundle("~/bundle")
            .Include("~/Content/static.js")
            .Include("~/signalr/hubs");
    
        bundles.Add(include);
    }
    

For some samples of virtual path providers + bundling, see Bundling and Minification and Embedded Resources or Bundling Dynamic Generated Controller / Action Content for example.

Другие советы

I'm not sure whether there is a way to do that, but another alternative is to generate the /signalr/hubs javascript at build time. That way you can just bundle the generated js file.

See the "How to create a physical file for the SignalR generated proxy" section in http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top