Question

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?

Était-ce utile?

La solution

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.

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top