如何在没有 HttpContext 的情况下使用捆绑包

本文关键字:情况下 HttpContext | 更新日期: 2023-09-27 18:35:14

我想在其他环境中获取捆绑包构建的字符串,例如:HttpApplication start,Console application等。

但是当我打电话

Scripts.Render("~/js").ToHtmlString()

将抛出异常:

Value cannot be null.
Parameter name: httpContext

如何模拟它以获得结果?

如何在没有 HttpContext 的情况下使用捆绑包

简短的回答:不,没有httpContext就无法使用Scripts.Render。但是,如果您愿意嘲笑它,可能会有一种解决方法(见下文)。

详细答案:Microsoft做出了一些不幸的设计决定。我已经反编译了 System.Web.Optimization (V1.1.0.0) 库(Microsoft.ASP.NET Web 优化框架的一部分,可通过 NUGET 获得)的 Render 方法,并发现: Scrips.Render(在内部调用Scripts.RenderFormat)调用Scripts.Manager.RenderExplicit(tagFormat, paths)以返回渲染结果。

该函数在内部使用 this.DeterminePathsToRender(paths) 通过使用 this.ResolveVirtualPath(current) 解析路径。如果你看一下它,你会发现它使用this._httpContext来解析路径:

internal string ResolveVirtualPath(string virtualPath)
{
    Uri uri;
    if (Uri.TryCreate(virtualPath, UriKind.Absolute, out uri))
    {
        return virtualPath;
    }
    string arg = "";
    if (this._httpContext.Request != null)
    {
        arg = this._httpContext.Request.AppRelativeCurrentExecutionFilePath;
    }
    return this.ResolveUrlMethod(arg, virtualPath);
}

所以不幸的是,没有办法绕过httpContext。我想到的另一种方法是从类脚本继承一个类 myScriptClass,然后通过 myScriptClass 构造函数设置内部属性 Context。但这也是不可能的,因为脚本是一个静态类,不能从中继承(有关详细信息,请参阅本主题)。


但是您可以使用BundleContext.HttpContext来获取或设置当前使用的 HttpContext。

但是,如果您只能访问特定的BundleCollection对象,则没有选择,因为它的.Context属性是内部的。

对于控制台应用程序,这意味着您可能必须创建一个假的请求对象和 HttpContext,在使用 render 方法之前,必须将其分配给 BundleContext.HttpContext。您可以查看此处那里以获取有关如何执行此操作的更多详细信息。