javascript - 手动使用 MVC 脚本捆绑

标签 javascript asp.net-mvc-4 scriptbundle

有没有办法以编程方式呈现脚本包?

在 MVC 中使用脚本包非常棒。喜欢它。使用它。

现在我正在编写一个使用自托管 WebApi 的应用程序,我还想在其中创建一个脚本包。 也就是说,我的项目中有许多 javascript 文件,我希望将它们缩小、组合,然后根据请求返回。

我想这应该是可能的。不过似乎找不到任何相关信息。

最佳答案

不幸的是,ASP.NET 捆绑机制与 ASP.NET 上下文紧密耦合。在自托管中使用它需要一些额外的工作。例如,您需要有一个自定义虚拟路径提供程序,它将能够从指定位置读取文件:

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);
        }
    }
}

然后您可以将一个bundle.config 文件附加到您的控制台应用程序,您可以在其中注册所有捆绑文件:

<?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>

接下来,您可以编写自己的主机,用我们刚刚编写的自定义虚拟路径提供程序替换默认的虚拟路径提供程序:

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();
        }
    }
}

最后,您可以拥有一些 API Controller ,它将为我们在 bundle.config 文件中定义的自定义 bundle 提供服务:

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
    {
    }
}

在此示例中,我省略了客户端缓存,您显然应该在 Controller 内部考虑该缓存,以便使用相应的 Cache header 提供捆绑内容。

关于javascript - 手动使用 MVC 脚本捆绑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22129539/

相关文章:

javascript - 部分 View 表单通过ajax提交返回部分 View

javascript - 如何阻止按钮被按下两次

javascript - 在 tumblr 中设置一个帖子标签?

javascript - Angular - 将两个可观察结果合并为一个

forms - 当 View 使用主布局时,MVC 4\表单提交按钮不起作用

javascript - div 的中心 - 中心点

c# - 连接到集线器的 SignalR 2.2.0 WebSocket 错误

.net - {version} 值如何填充到 BundleConfig 文件中?

twitter-bootstrap - MVC 4 Styles.Render & Scripts.Render 说明