首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ASP.NET在捆绑中使用嵌入式资源

ASP.NET在捆绑中使用嵌入式资源
EN

Stack Overflow用户
提问于 2016-01-14 10:30:32
回答 2查看 2.6K关注 0票数 15

我试图实现一种通用方法,为我的web解决方案中的不同程序集使用嵌入式资源中的JavaScript和CSS文件提供可能性。这篇博客文章展示了一种使用VirtualPathProvider的技术。这很好,但是VirtualPathProvider需要包含在每个包含嵌入式资源的程序集中。

我试图从博客文章中增强VirtualPathProvider,以便将程序集传递到它,并从它的程序集加载资源:

代码语言:javascript
复制
public EmbeddedVirtualPathProvider(VirtualPathProvider previous, Assembly assembly)
{
    this.previous = previous;
    this.assembly = assembly;
}

初始化时,它从传递的程序集中读取所有嵌入的资源:

代码语言:javascript
复制
protected override void Initialize()
{
    base.Initialize();

    this.assemblyResourceNames = this.assembly.GetManifestResourceNames();
    this.assemblyName = this.assembly.GetName().Name;
}

GetFile从传递的程序集读取内容:

代码语言:javascript
复制
public override VirtualFile GetFile(string virtualPath)
{
    if (IsEmbeddedPath(virtualPath))
    {
        if (virtualPath.StartsWith("~", System.StringComparison.OrdinalIgnoreCase))
        {
            virtualPath = virtualPath.Substring(1);
        }

        if (!virtualPath.StartsWith("/", System.StringComparison.OrdinalIgnoreCase))
        {
            virtualPath = string.Concat("/", virtualPath);
        }

        var resourceName = string.Concat(this.assembly.GetName().Name, virtualPath.Replace("/", "."));
        var stream = this.assembly.GetManifestResourceStream(resourceName);

        if (stream != null)
        {
            return new EmbeddedVirtualFile(virtualPath, stream);
        }
        else
        {
            return _previous.GetFile(virtualPath);
        }
    }
    else
        return _previous.GetFile(virtualPath);
}

通过检查Initialize方法中读取的资源名来检查资源是否是此程序集的嵌入式资源:

代码语言:javascript
复制
private bool IsEmbeddedPath(string path)
{
    var resourceName = string.Concat(this.assemblyName, path.TrimStart('~').Replace("/", "."));
    return this.assemblyResourceNames.Contains(resourceName, StringComparer.OrdinalIgnoreCase);
}

我将EmbeddedVirtualPathProvider类移动到主web项目(ProjectA),这样它就不需要包含在每个包含嵌入式资源的程序集中,并使用Global.asax中的以下代码注册它

代码语言:javascript
复制
HostingEnvironment.RegisterVirtualPathProvider(
    new EmbeddedVirtualPathProvider(
        HostingEnvironment.VirtualPathProvider,
        typeof(ProjectB.SomeType).Assembly));

在包含嵌入式资源(ProjectB)的项目中,我仍然在PostApplicationStartMethod中创建以下包

代码语言:javascript
复制
 BundleTable.Bundles.Add(new ScriptBundle("~/Embedded/Js")
     .Include("~/Scripts/SomeFolder/MyScript.js")
 );

Scripts/MyScript.js是ProjectB中的嵌入式资源。

有了这一点,我将得到以下例外:

目录'C:\webs\ProjectA\Scripts\SomeFolder\‘不存在。无法开始监视文件更改。

更新的完整堆栈跟踪可用在这个要旨中。

更新,VirtualPathProvider本身似乎也运行得很好。如果我直接加载文件,而不是通过包加载文件,并在web.config中设置以下条目,它将从ProjectB加载嵌入的javascript:

代码语言:javascript
复制
<system.webServer>
  <handlers>
    <add name="MyStaticFileHandler" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler"/>
  </handlers>
</system.webServer>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-22 15:11:20

当ASP.net优化创建包时,它为脚本的虚拟目录调用GetCacheDependency。您的GetCacheDependency实现只检查虚拟文件,对于虚拟目录,它依赖于基本VirtualPathProvider,它检查目录是否存在并失败。

要解决这个问题,您必须检查路径是否是某个脚本的目录,并为GetCacheDependency返回null。

要安全地确定virtualPath是否是包目录,可以使用BundleTable.Bundles集合或使用约定(即:每个包应该以~/Embedded开头)。

代码语言:javascript
复制
public override CacheDependency GetCacheDependency(
    string virtualPath, 
    IEnumerable virtualPathDependencies, 
    DateTime utcStart)
{
    // if(virtualPath.StartsWith("~/Embedded"))
    if(BundleTables.Bundles.Any(b => b.Path == virtualPath))
    {
        return null; 
    }
    if (this.IsEmbeddedPath(virtualPath))
    {
        return null;
    }
    else
    {
        return this._previous
                   .GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2020-06-14 10:46:03

关于以下错误

目录'C:\webs\ProjectA\Scripts\SomeFolder\‘不存在。无法开始监视文件更改。

如果SomeFolder的所有资源文件都是嵌入式的,因此在已发布的站点中-它没有创建这个文件夹,就会发生这种情况。

对于bundle,它在创建包时保留时间戳,并监视文件夹中的任何文件更改,以触发包文件中的更新。

这里-在SomeFolder中没有要监视的文件-因为所有的文件都是嵌入的。没有找到阻止文件夹监视的方法--但是通过处理这个特定的异常,它可以被忽略。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34787206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档