Asp.Net中虚拟文件系统的使用


具体实现步骤如下:
一、开发web用户控件
这一步和以前的开发没有区别。
1、首先新建一个web应用程序(需要VS2005 sp1支持)
2、然后在里面开发几个web用户控件
3、在ascx文件上右键-〉属性-〉生成操作选择嵌入的资源
4、生成dll就可以了(dll的名字为:Test.Control.dll,后面会用到)

二、开发一个虚拟文件系统提供类
这一步是最重要的一步。
具体思路就是:在系统中注册这个类,然后在每访问一个文件/资源的时候会自动调用这个类,在这个类中判断文件的路径是否是我们定义的,如果是就用我们的逻辑来处理,即从dll中取出资源。
首先把类的代码贴出来,我想可能许多人应该和我一样,喜欢直接先看代码:)
DllVirtualPathProvider
    public class DllVirtualPathProvider : System.Web.Hosting.VirtualPathProvider
    
{
        
public DllVirtualPathProvider()
        
{
        }


        
public override string CombineVirtualPaths(string basePath, string relativePath)
        
{
            
if (IsAppResourcePath(basePath))
            
{
                
return null;
            }


            
return Previous.CombineVirtualPaths(basePath, relativePath);
        }


        
public override System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)
        
{
            
return Previous.CreateObjRef(requestedType);
        }


        
public override bool DirectoryExists(string virtualDir)
        
{
            
if (IsAppResourcePath(virtualDir))
            
{
                
return true;
            }

            
else
            
{
                
return Previous.DirectoryExists(virtualDir);
            }


        }


        
public override string GetCacheKey(string virtualPath)
        
{
            
if (IsAppResourcePath(virtualPath))
            
{
                
return null;
            }

            
else
            
{
                
return Previous.GetCacheKey(virtualPath);
            }

        }


        
public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
        
{
            
if (IsAppResourcePath(virtualPath))
            
{
                
return null;
            }

            
else
            
{
                
return Previous.GetFileHash(virtualPath, virtualPathDependencies);
            }

        }


        
private bool IsAppResourcePath(string virtualPath)
        
{
            String checkPath 
= VirtualPathUtility.ToAppRelative(virtualPath);
            
return checkPath.StartsWith("~/MyUserControl/Test.Control.dll/", StringComparison.InvariantCultureIgnoreCase);
        }


        
public override bool FileExists(string virtualPath)
        
{
            
return (IsAppResourcePath(virtualPath) || Previous.FileExists(virtualPath));
        }


        
public override VirtualFile GetFile(string virtualPath)
        
{
            
if (IsAppResourcePath(virtualPath))
            
{
                
return new AssemblyResourceVirtualFile(virtualPath);
            }

            
else
            
{
                
return Previous.GetFile(virtualPath);
            }

        }


        
public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath,
               System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
        
{
            
if (IsAppResourcePath(virtualPath))
            
{
                
string path = HttpRuntime.AppDomainAppPath + virtualPath.Substring(1);

                
return new System.Web.Caching.CacheDependency(path);
            }

            
else
            
{
                
return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
            }

        }

    }
重点有以下几个:
1、必须从VirtualPathProvider类继承
2、IsAppResourcePath方法是用来判断是否为我们定义的路径格式:~/MyUserControl/Test.Control.dll/,下面调用的时候就使用这个路径
3、注意GetCacheKey方法:
        public override string GetCacheKey(string virtualPath)
        
{
            
if (IsAppResourcePath(virtualPath))
            
{
                
return null;
            }

            
else
            
{
                
return Previous.GetCacheKey(virtualPath);
            }

        }
这里当符合条件时一定要返回null,如果返回"",会导致所有的用户控件都使用一个key值,从而所有的用户控件都显示同样的内容了。如果返回其他非空字符,会报异常(它会去查找cache,我们是没有的)
另外所有的方法当不符合我们的条件时一定要调用 Previous.**** 因为系统中可能有多个虚拟文件提供程序的。

4、GetCacheDependency方法:
if (IsAppResourcePath(virtualPath))
            
{
                
string path = HttpRuntime.AppDomainAppPath + virtualPath.Substring(1);

                
return new System.Web.Caching.CacheDependency(path);
            }
这个方法是用来决定Cache的使用的,如果返回null,会导致性能严重下降,每次调用用户控件时都会重新编译,这里返回的当前路径(需要在网站目录下再建立子目录:MyUserControl\Test.Control.dll),这个目录下是空的,这样当每次取Cache时都会认为我们的ascx没有修改,不需要重新编译。

5、在GetFile方法中我们返回的是一个AssemblyResourceVirtualFile类:
    class AssemblyResourceVirtualFile : VirtualFile
    
{
        
string path;
        
public AssemblyResourceVirtualFile(string virtualPath)
            : 
base(virtualPath)
        
{
            path 
= VirtualPathUtility.ToAppRelative(virtualPath);
        }


        
public override System.IO.Stream Open()
        
{
            
string[] parts = path.Split('/');
            
string assemblyName = parts[2];
            
string resourceName = parts[3];
            assemblyName 
= Path.Combine(HttpRuntime.BinDirectory, assemblyName);
            System.Reflection.Assembly assembly 
= System.Reflection.Assembly.LoadFrom(assemblyName);
            
if (assembly != null)
            
{
                
return assembly.GetManifestResourceStream(resourceName);
            }

            
return null;
        }

    }
这个类的目的就是从我们的dll中读出资源文件。

三、注册这个虚拟文件提供程序
这一个很简单,在global.asax中注册:
        protected void Application_Start(object sender, EventArgs e)
        
{
            System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(
new DllVirtualPathProvider());
        }

四、调用dll中的用户控件
                Control control1 = this.LoadControl("/MyUserControl/Test.Control.dll/Test.Control.Sample.List.ascx");
                Control control2 
= this.LoadControl("/MyUserControl/Test.Control.dll/Test.Control.Sample.Sample.ascx");

                form1.Controls.Add(control1);
                form1.Controls.Add(control2);
比较简单,就是路径要和前面的一致。

后记:
首先感谢 Leepy  同志认真踏实的精神,找出了我这篇文章中的一个BUG。
原来我的第四步:调用dll中的用户控件,是一个web应用程序,如果是一个web站点的话就会出现问题。因为在VS2005中调试时这两种方式呈现出来的Url是不一样的:
web应用程序:http://localhost:****/Default.aspx
web站点     :http://localhost:****/WebSite1/Default.aspx
也就是说我原来的程序没有考虑到非根目录部署的情况,针对这个BUG要修改的地方有(为了BUG的原始记录,我就不在原文中修改了,把修改点列在下面):
1、GetCacheDependency方法:
GetCacheDependency
    public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath,
           System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
    
{
        
if (IsAppResourcePath(virtualPath))
        
{
            
string path = HttpRuntime.BinDirectory;

            
return new System.Web.Caching.CacheDependency(path);
        }

        
else
        
{
            
return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
        }

    }
这里改成直接改成当前网站的bin目录还可以省掉建空目录的步骤了

2、在调用的地方修改成以下方式:
        Control control1 = this.LoadControl("~/MyUserControl/MyWebApplication.dll/MyWebApplication.Sample1.ascx");
        Control control2 
= this.LoadControl("~/MyUserControl/MyWebApplication.dll/MyWebApplication.Sample2.ascx");

        form1.Controls.Add(control1);
        form1.Controls.Add(control2);

转载于:https://www.cnblogs.com/Ewin/archive/2008/05/07/1187298.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262854.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打印流

一、打印流输出数据到文件 全路径,没有操作系统没有E盘,异常; 二、打印流修改打印输出路径 会生成一个记录的文件: 可用来记录一些操作日志; 转载于:https://www.cnblogs.com/wmqiang/p/11374696.html

throw()使用小结

为什么要加一个throw()到你的函数中?这是异常规范,只会出现在声明函数中,表示这个函数可能抛出任何类型的异常void GetTag() throw(int);表示只抛出int类型异常void GetTag() throw(int,char);表示抛出in,char类型异常…

乘法表

叙述性说明 法表或许将会扎根于我们一生的记忆,如今让我们重温那些温暖的记忆,请编程输出九九乘法表. 如今要求你输出它的格式与寻常的 不同啊! 是那种反过来的三角形啦,详细例如以下图: 每两个式子之前用一个空格 隔开。。。 输…

DropDownList实现无限级分类

要想实现无限级分类,那得还用传统的老方法----递归,也许有很多人会抱怨递归的性能不是太理想。俗话说的话,能抓到老鼠的猫就是好猫。我提倡先解决问题,然后再优化性能。 数据库结构: 代码: protectedvoidGe…

50张非常精美的Apple主题桌面壁纸(上篇)

今天这篇文章向大家分享50张非常精美的Apple主题桌面壁纸,果粉们赶紧来下载啊。 Blue Apple wallpaper Apple Lawn .wallpaper. by ~VertigoStudio A quite simple Wallpaper, without mutch falderal Green Apple PSP by ~ARVQ Mac Apple Wallpapers With Android …

WPF- 关于自定义Calendar控件

由于项目对更改日期 时间的需要,接触了一下Calendar控件。结果发现在这么强大的控件的背后,微软其实并没有为开发人员留有很强的扩展性。 (项目要求的Calendar控件能对一些特定的日期进行特殊处理,如高亮,以及类似于Ou…

[文摘]上软解散相关

真实系列文摘 之 上海软星仙剑开发组解散真正内幕-----附.上软人最后留给玩家的话我不是个疯狂的仙剑迷, 但我有朋友是; 我不是个对看不管惯的社会现象能挺身而出的人, 但还是喜欢去在意去关心那些事...下面这个算不上是什么新闻了, 但如过是玩过仙剑系列觉得还不错的人, 对游戏…

Apache Spark 1.5发布,新特性一览

Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架。最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一。Apache Spark社区刚刚发布了1.5版本,明略数据高级工程师梁堰波解析了该版本中的众多新特性&am…

js正则表达exec和match的区别(转)

转自:http://blog.csdn.net/fushou/article/details/6934608 以前用js很少用到js的正则表达式,即使用到了,也是诸如邮件名称之类的判断,网上代码很多,很少有研究,拿来即用。 最近开发遇到一些需要使用正则表达式&#…

微软推出免费在线系统诊断工具--不用手动下载

在运行框中输入以下地址:\\live.sysinternals.com,所有工具都在Tools下,Files目录有可供下载的压缩包。。Microsoft Corp. has launched a beta service that lets Windows users launch the Sysinternals library of free diagnostic and tr…

开源软件

邮件服务器: Postfixftp服务器: vsftpd统计: nginx access log awstats 统计: google统计 google分析 腾讯分析 分布式锁及配置管理:Zookeeper php框架:thinkphp运维监控: cacti数据同步&#…

cad.net 获取所有已经安装的cad版本信息

计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\Hardcopy 转载于:https://www.cnblogs.com/JJBox/p/11381254.html

Restangular的使用

2019独角兽企业重金招聘Python工程师标准>>> // First way of creating a Restangular object. Just saying the base URL var baseAccounts Restangular.all(accounts); // This will query /accounts and return a promise. baseAccounts.getList().then(functio…

浅析数据质量检查

What are the four broad categories of data quality checks? Provide an implementation technique for each. 数据质量检查的四大类是什么?为每类提供一种实现技术。 答:数据质量检查是ETL工作中非常重要的一步,主要关注一下四个方面。 1…

在用dw.GetSqlSelect()获得到的Sql语句出现PBSELECT( VERSION的解决办法

在用dw.GetSqlSelect()获得到的Sql语句出现PBSELECT( VERSION的解决办法: 把数据窗口的数据源转换到syntax模式下就行了 ! 转载于:https://www.cnblogs.com/Tonyyang/archive/2008/06/03/1212689.html

刚发现的2011年最给力的春联

上联:房价涨.地价涨.油价涨.电价涨.水价涨.粮价涨.肉价涨.蛋价涨.菜价涨.药价涨.这也涨.那也涨.怎一个涨字了得.涨了还涨。 下联:上学难.参军难.就业难.买房难.租房难.择偶难.结婚难.育儿难.就医难.养老难.男也难.女也难.看世间难字当头.难上加难 横批:活…

SQL Server的镜像是基于物理块变化的复制 镜像Failover之后数据的预热问题

SQL Server的镜像是基于物理块变化的复制 镜像Failover之后数据的预热问题 基于物理块变化的复制,没有并行也是很快的。 逻辑复制的日志是按事务结束的时间排序的,而物理复制是与事务无关的,只要发生了改变,就可以立即传送到备库&…

VSS不需要验证自动登录的问题

新项目要开始了,搭建好开发环境以及项目框架后,遇到第一个问题就是我自己的机子打开VS不需要登陆VSS就直接打开了解决方案,而其他的同事则没有遇到这样的情况,于是搜索了下原因,发现是设置问题: 1,在VSS管理器中》工具》选项》允许网络用户名自动登录 这个选项去掉 …

说说“开源杀死商业开发工具”

今天在Solidot看到一条很有意思的短文,标题是“开源杀死商业开发工具”,其文如下: UNA,源自拉丁形容词“together”,是一种协作式的实时源代码开发环境,允许两个或更多的开发者同时编辑相同的代码。支持大部…

ubuntu22.04 安装vscode

安装 Visual Studio Code(VSCode)在 Ubuntu 22.04 系统上是一个简单的过程。以下是步骤指南: 更新系统软件包列表: 打开终端,并执行以下命令来更新您的系统软件包列表: sudo apt update安装依赖包&#xff…