如何在虚拟路径提供程序中加载静态文件(例如图像)

时间:2016-03-09 13:53:44

标签: c# asp.net-mvc virtualpathprovider

我想问一个关于加载静态文件(例如.png文件)和使用虚拟路径提供程序的问题。

所以,我用App_Start创建了项目:

    public static void Start()
    {
        ConfigureBundles();
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        //etc.
    }

    private static void ConfigureBundles()
    {
        BundleTable.EnableOptimizations = true;
        BundleTable.VirtualPathProvider = new EmbeddedVirtualPathProvider(HostingEnvironment.VirtualPathProvider);
    }

在另一个类中准备覆盖方法:

// virtual path
public class EmbeddedVirtualPathProvider : VirtualPathProvider
{
    private VirtualPathProvider _previous;
    public EmbeddedVirtualPathProvider(VirtualPathProvider previous)
    {
        _previous = previous;
    }
    public override bool FileExists(string virtualPath)
    {
        if (IsEmbeddedPath(virtualPath))
            return true;
        else
            return _previous.FileExists(virtualPath);
    }
    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
    {
        if (IsEmbeddedPath(virtualPath))
        {
            return null;
        }
        else
        {
            return _previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
        }
    }
    public override VirtualDirectory GetDirectory(string virtualDir)
    {
        return _previous.GetDirectory(virtualDir);
    }
    public override bool DirectoryExists(string virtualDir)
    {
        return _previous.DirectoryExists(virtualDir);
    }
    public override VirtualFile GetFile(string virtualPath)
    {
        if (IsEmbeddedPath(virtualPath))
        {
            string fileNameWithExtension = virtualPath.Replace("~/", string.Empty).Replace("/", ".").Replace("\\", ".").TrimStart(new char[] { '.' });
            string nameSpace = "myApp";
            string manifestResourceName = string.Format("{0}.{1}", nameSpace, fileNameWithExtension);
            Stream stream = null;

            foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName.StartsWith("myApp")).ToList())
            {
                stream = assembly.GetManifestResourceStream(manifestResourceName);
                if (stream != null)
                    break;
            }
            return new EmbeddedVirtualFile(virtualPath, stream ?? new MemoryStream());
        }
        else
            return _previous.GetFile(virtualPath);
    }
    private bool IsEmbeddedPath(string path)
    {
        return path.Contains("Scripts") || path.Contains("Content") || path.Contains("bundles") || path.Contains("Fonts") || path.Contains("Gfx");
    }
}
public class EmbeddedVirtualFile : VirtualFile
{
    private Stream _stream;
    public EmbeddedVirtualFile(string virtualPath, Stream stream)
        : base(virtualPath)
    {
        _stream = stream;
    }
    public override Stream Open()
    {
        return _stream;
    }
}

最后一步我准备Global.asax:

    public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ConfigureBundles();
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

    private static void ConfigureBundles()
    {
        BundleTable.EnableOptimizations = true;
        BundleTable.VirtualPathProvider = new EmbeddedVirtualPathProvider(HostingEnvironment.VirtualPathProvider);
    }
}

我的所有css文件和js文件都已在Embedded Resource上设置了Build Action,这在我的主项目中运行良好。

如果我希望静态文件以相同的方式从外部程序集加载到主项目中,我该怎么办?

感谢您的帮助!!

0 个答案:

没有答案