我想在其他环境中获取捆绑包构建的字符串,例如:HttpApplication 启动、控制台应用程序等。
但是当我打电话
Scripts.Render("~/js").ToHtmlString()
将抛出异常:
Value cannot be null.
Parameter name: httpContext
如何模拟它以获得结果?
我想在其他环境中获取捆绑包构建的字符串,例如:HttpApplication 启动、控制台应用程序等。
但是当我打电话
Scripts.Render("~/js").ToHtmlString()
将抛出异常:
Value cannot be null.
Parameter name: httpContext
如何模拟它以获得结果?
简短回答:Scripts.Render
不,没有 httpContext就无法使用。但是,如果您愿意模拟它,可能会有一种解决方法(见下文)。
详细回答:
微软做出了一些不幸的设计决定。我已经反编译了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。我想到的另一种方法是从类 Scripts 继承一个类 myScriptClass,然后通过 myScriptClass 构造函数设置内部属性 Context。但这也是不可能的,因为 Scripts 是一个无法继承的静态类(有关详细信息,请参阅本主题)。
但是你可以使用BundleContext.HttpContext
来获取或设置当前使用的HttpContext。
但是,如果您只能访问特定BundleCollection
对象,那么您就别无选择,因为它的.Context
属性是内部的。
对于控制台应用程序,这意味着您可能必须创建一个假请求对象和 HttpContext,您必须在使用渲染方法之前将其分配给 BundleContext.HttpContext。您可以查看此处或此处以获取更多详细信息。