Reputation: 199
Is there a way to programmatically render a script bundle?
Using script bundles in MVC is great. Like it. Use it.
Now I'm writing an application that uses Self-Host WebApi in which I'd like to also create a script bundle. That is, I have a number of javascript files in the project that I wish to minify, combine and then return upon request.
I guess this should be possible. Can't seem to find any info on it, though.
Upvotes: 0
Views: 754
Reputation: 1038710
Unfortunately the ASP.NET bundling mechanism is tightly coupled with an ASP.NET context. Using it in a self host would require some additional work. For example you will need to have a custom virtual path provider which will be able to read files from a specified location:
internal class MyVirtualPathProvider : VirtualPathProvider
{
private readonly string basePath;
public MyVirtualPathProvider(string basePath)
{
this.basePath = basePath;
}
public override bool FileExists(string virtualPath)
{
return File.Exists(this.GetFileName(virtualPath));
}
public override VirtualFile GetFile(string virtualPath)
{
return new MyVirtualFile(this.GetFileName(virtualPath));
}
private string GetFileName(string virtualPath)
{
return Path.Combine(this.basePath, virtualPath.Replace("~/", ""));
}
private class MyVirtualFile : VirtualFile
{
private readonly string path;
public MyVirtualFile(string path)
: base(path)
{
this.path = path;
}
public override Stream Open()
{
return File.OpenRead(this.path);
}
}
}
then you could have a bundle.config file attached to your console application where you would register all your bundle files:
<?xml version="1.0" encoding="utf-8" ?>
<bundles version="1.0">
<scriptBundle path="~/bundles/myBundle">
<include path="~/foo.js" />
<include path="~/bar.js" />
</scriptBundle>
</bundles>
next you could write your self-host where you would replace the default virtual path provider with the custom one we have just written:
class Program
{
static void Main()
{
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Routes.MapHttpRoute(
"API Default",
"api/{controller}/{id}",
new { id = RouteParameter.Optional }
);
BundleTable.VirtualPathProvider = new MyVirtualPathProvider(Environment.CurrentDirectory);
using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
}
and finally you could have some API controller which will serve the custom bundle that we defined in our bundle.config
file:
public class MyScriptsController: ApiController
{
public HttpResponseMessage Get()
{
string bundlePath = "~/bundles/myBundle";
var bundle = BundleTable.Bundles.GetBundleFor(bundlePath);
var context = new BundleContext(new HttpContext(), BundleTable.Bundles, bundlePath);
var response = bundle.GenerateBundleResponse(context);
return new HttpResponseMessage()
{
Content = new StringContent(response.Content, Encoding.UTF8, "text/javascript"),
};
}
private class HttpContext : HttpContextBase
{
}
}
In this example I have omitted the client side caching that you should obviously take into account inside the controller in order to serve the bundled content with the corresponding Cache
headers.
Upvotes: 2