当前位置: 首页 > news >正文

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

在Asp.Net的开发过程中页面文件等都是放在当前网站目录下的,其实我们可以利用.Net2.0新增的 虚拟文件系统(VirtualPathProvider) 将页面、图片等信息保存到数据库或其他目录中去,达到灵活配置。
本文以一个例子来说明 虚拟文件系统 的使用,要实现的功能场景描述如下:
以前开发Asp.Net的web用户控件时,需要把用户控件和当前项目作为同一个项目时才能正常使用,而且发布时需要把dll文件和所有的ascx文件都发布才能使用;另外也不方便作为公用类给其他人使用
利用虚拟文件系统后可以把ascx文件作为资源打包到dll中,下次只要有这个dll就可以使用了,不需要ascx文件,很方便。

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

二、开发一个虚拟文件系统提供类
这一步是最重要的一步。
具体思路就是:在系统中注册这个类,然后在每访问一个文件/资源的时候会自动调用这个类,在这个类中判断文件的路径是否是我们定义的,如果是就用我们的逻辑来处理,即从dll中取出资源。
首先把类的代码贴出来,我想可能许多人应该和我一样,喜欢直接先看代码:)
DllVirtualPathProvider
重点有以下几个:
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
这里改成直接改成当前网站的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);

    本文转自永春博客园博客,原文链接:http://www.cnblogs.com/firstyi/archive/2008/04/19/1161431.html,如需转载请自行联系原作者




相关文章:

  • yum管理详解
  • mysql数据库操纵语言
  • Centos7系列(三)防火墙与网络区域详解
  • table的使用以及其内padding、margin的实现
  • 判断点是否在多边形内部
  • 算法系列——算法入门之递归分而治之思想的实现
  • 建立名称server
  • Hyper-V Server增强会话模式
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • Spring AOP 1
  • 如何启动Nunit的调试功能
  • ELK日志分析系统实战(一)安装和部署
  • H3C路由器登录管理
  • Laravel5.1 条件性验证
  • Redhat7 增加swap分区
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • emacs初体验
  • Github访问慢解决办法
  • Hibernate【inverse和cascade属性】知识要点
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Java精华积累:初学者都应该搞懂的问题
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • Spring声明式事务管理之一:五大属性分析
  • Transformer-XL: Unleashing the Potential of Attention Models
  • V4L2视频输入框架概述
  • vue中实现单选
  • web标准化(下)
  • 前端临床手札——文件上传
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 深度解析利用ES6进行Promise封装总结
  • 学习JavaScript数据结构与算法 — 树
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 1.Ext JS 建立web开发工程
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • #Lua:Lua调用C++生成的DLL库
  • #每日一题合集#牛客JZ23-JZ33
  • $.ajax,axios,fetch三种ajax请求的区别
  • (4)Elastix图像配准:3D图像
  • (4)logging(日志模块)
  • (9)STL算法之逆转旋转
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (离散数学)逻辑连接词
  • (一)Java算法:二分查找
  • (转)大型网站架构演变和知识体系
  • .bat批处理出现中文乱码的情况
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net Application的目录
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .Net6 Api Swagger配置
  • .net和jar包windows服务部署
  • .net连接oracle数据库
  • @Bean, @Component, @Configuration简析