I'm trying to use the technique described in this blog to add embedded dll resources to my bundles.
I have created the custom VirtualPathProvider
below.
public class EmbeddedVirtualPathProvider : VirtualPathProvider {
private Type _rootType;
public EmbeddedVirtualPathProvider(Type rootType) {
_rootType = rootType;
}
public override bool FileExists(string virtualPath) {
if (IsEmbeddedPath(virtualPath))
return true;
else
return Previous.FileExists(virtualPath);
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) {
if (IsEmbeddedPath(virtualPath)) {
return null;
}
else {
return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
public override VirtualDirectory GetDirectory(string virtualDir) {
return Previous.GetDirectory(virtualDir);
}
public override bool DirectoryExists(string virtualDir) {
return Previous.DirectoryExists(virtualDir);
}
public override VirtualFile GetFile(string virtualPath) {
if (IsEmbeddedPath(virtualPath)) {
string fileNameWithExtension = virtualPath.Substring(virtualPath.LastIndexOf("/") + 1);
string nameSpace = _rootType.Namespace;
string manifestResourceName = String.Format("{0}.{1}", nameSpace, fileNameWithExtension);
var stream = _rootType.Assembly.GetManifestResourceStream(manifestResourceName);
return new EmbeddedVirtualFile(virtualPath, stream);
}
else
return Previous.GetFile(virtualPath);
}
private bool IsEmbeddedPath(string path) {
return path.Contains("~/Embedded");
}
}
public class EmbeddedVirtualFile : VirtualFile {
private Stream _stream;
public EmbeddedVirtualFile(string virtualPath, Stream stream)
: base(virtualPath) {
_stream = stream;
}
public override Stream Open() {
return _stream;
}
}
I then register this and set up the bundles;
public static void RegisterBundles(BundleCollection bundles) {
HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedVirtualPathProvider(typeof(My.Custom.Type)));
bundles.Add(new StyleBundle("~/Embedded/css").Include(
"~/Embedded/files/styles/etc/styles.css")
);
}
I have also implemented a custom EmbeddedResourceHttpHandler
as described in the article which works when requesting the file as a direct http request.
Problem:
The embedded files aren't being included in the bundle, they're just ignored. When debugging the FileExists
method is called several times but never for ~/Embedded/files/styles/etc/styles.css
What am I missing?
Secondary Problem
When using the latest version of the Microsoft ASP.NET Web Optimization Framework. The VirtualPathProvider
works as expected, however it prevents the IRouteHandler
from executing. If the FileExists
method is changed to return false this allows the RouteHandler to execute but obviously breaks the VirtualPathProvider
.
I'm assuming it's not using a configured route because it's looking for a physical file when FileExists
returns true? Is this a configuration or an implementation issue?
Bundling and minification are two techniques you can use in ASP.NET to improve page load performance for your web application. Bundling combines multiple files into a single file. Minification performs a variety of different code optimizations to scripts and CSS, which results in smaller payloads.
BundlerMinifier is the default choice for ASP.NET Core application for bundling and minification. It is a simple package bundler integrated with the ASP.NET Core project build system.
To optimize the performance of an application I found that bundling and minification can significantly improve the performance. It can be applied on MVC as well as in ASP.NET web forms.
You can see ScriptBundle and StyleBundle objects we are using for bundling the js and CSS types of files. ScriptBundle: is responsible for Script files i.e javascript (JS). StyleBundle: is responsible for stylesheet files i.e CSS.
You will need to tell the BundleTable to use your VirtualPathProvider like this:
BundleTable.VirtualPathProvider = new EmbeddedVirtualPathProvider(typeof(My.Custom.Type));
This functionality was added in v1.1.0 of the Microsoft ASP.NET Web Optimization Framework.
Also you need to make sure that requests for CSS file go through the ASP.NET pipeline by adding this to your web.config.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
The secondary problem can be solved by setting RouteCollection.RouteExistingFiles
to true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With