通过VirtualPathProvider使用嵌入资源

VirtualPathProvider类,提供了一组方法,使 Web 应用程序可以从虚拟文件系统中检索资源。

参见MSDN:http://msdn.microsoft.com/zh-cn/library/system.web.hosting.virtualpathprovider.aspx

 

遇到这样一个需求,要将.ascx作为嵌入资源放到一个Library项目中,在Web App中需要可以使用。

 

上网查找后发现,VirtualPathProvider类可以实现这个目的。

 

步骤一:

通过继承VirtualPathProvider类,实现自己的AssemblyResourceVirtualPathProvider,用来为Assembly中的Resource提供支持。

 

VirtualPathProvider代码

    
public   class  AssemblyResourceVirtualPathProvider : System.Web.Hosting.VirtualPathProvider
    {
        
///   <summary>
        
///  AssemblyPath与VirtualPath映射
        
///   </summary>
         private   string  _VirtualPath;
        
private   string  _AssemblyPath;

        
private   string  VirtualPath {  get  {  return  _VirtualPath; } }
        
private   string  AssemblyPath {  get  {  return  _AssemblyPath; } }

        
public  AssemblyResourceVirtualPathProvider( string  virtualPath,  string  assemblyPath)
        {
            _VirtualPath 
=   " ~/ "   +  virtualPath;
            _AssemblyPath 
=  assemblyPath;
        }

        
///   <summary>
        
///  是否是AssemblyResource类型的VirtualPath
        
///   </summary>
        
///   <param name="virtualPath"> virtualPath </param>
        
///   <returns></returns>
         private   bool  IsAssemblyResourceVirtualPath( string  virtualPath)
        {
            
string  path  =  VirtualPathUtility.ToAppRelative(virtualPath);
            
return  path.StartsWith(VirtualPath, StringComparison.InvariantCultureIgnoreCase);
        }

        
///   <summary>
        
///  获取virtualPath对应Assembly内的ResourceName
        
///   </summary>
        
///   <param name="virtualPath"> virtualPath </param>
        
///   <returns></returns>
         private   string  GetResourceName( string  virtualPath)
        {
            
return  VirtualPathUtility.GetFileName(virtualPath);
        }

        
#region  override

        
///   <summary>
        
///  获取VirtualFile
        
///   </summary>
        
///   <param name="virtualPath"></param>
        
///   <returns></returns>
         public   override  VirtualFile GetFile( string  virtualPath)
        {
            
if  (IsAssemblyResourceVirtualPath(virtualPath))
            {
                
string  resourceName  =   this .GetResourceName(virtualPath);
                
return   new  AssemblyResourceVirtualFile(virtualPath, AssemblyPath, resourceName);
            }
            
else
            {
                
return  Previous.GetFile(virtualPath);
            }
        }

        
///   <summary>
        
///  virtualPath指定的文件是否存在。
        
///   </summary>
        
///   <param name="virtualPath"></param>
        
///   <returns></returns>
         public   override   bool  FileExists( string  virtualPath)
        {
            
if  (IsAssemblyResourceVirtualPath(virtualPath))
            {
                
// return true;
                Assembly assembly  =  Assembly.LoadFrom(AssemblyPath);
                
if  (assembly  !=   null )
                {
                    
string  resourceName  =   this .GetResourceName(virtualPath);
                    
return  (assembly.GetManifestResourceInfo(resourceName)  !=   null );
                }
                
return   false ;
            }
            
else
            {
                
return  Previous.FileExists(virtualPath);
            }
        }

        
public   override   bool  DirectoryExists( string  virtualDir)
        {
            
if  (IsAssemblyResourceVirtualPath(virtualDir))
            {
                
return   true ;
            }
            
else
            {
                
return  Previous.DirectoryExists(virtualDir);
            }
        }

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

            
// HashCodeCombiner combiner = new HashCodeCombiner();
            
// foreach (string str in virtualPathDependencies)
            
// {
            
//     string fileName = HostingEnvironment.MapPathInternal(str);
            
//     combiner.AddFile(fileName);
            
// }
            
// return combiner.CombinedHashString;
        }

        
public   override  CacheDependency GetCacheDependency( string  virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            
return   null ;

            
// System.Collections.Specialized.StringCollection fullPathDependencies = null;

            
/// / Get the full path to all dependencies.
             // foreach (string virtualDependency in virtualPathDependencies)
            
// {
            
//     if (fullPathDependencies == null)
            
//         fullPathDependencies = new System.Collections.Specialized.StringCollection();

            
//     fullPathDependencies.Add(virtualDependency);
            
// }
            
// if (fullPathDependencies == null)
            
//     return null;

            
/// / Copy the list of full-path dependencies into an array.
             // string[] fullPathDependenciesArray = new string[fullPathDependencies.Count];
            
// fullPathDependencies.CopyTo(fullPathDependenciesArray, 0);
             /// / Copy the virtual path into an array.
             // string[] virtualPathArray = new string[1];
            
// virtualPathArray[0] = virtualPath;

            
// return new CacheDependency(virtualPathArray, fullPathDependenciesArray, utcStart);
        }

        
// public override string CombineVirtualPaths(string basePath, string relativePath)
        
// {
        
//     if (IsAssemblyResourceVirtualPath(basePath))
        
//     {
        
//         return null;
        
//     }
        
//     else
        
//     {
        
//         return Previous.CombineVirtualPaths(basePath, relativePath);
        
//     }
        
// }

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

        
// public override string GetCacheKey(string virtualPath)
        
// {
        
//     if (IsAssemblyResourceVirtualPath(virtualPath))
        
//     {
        
//         return null;
        
//     }
        
//     else
        
//     {
        
//         return Previous.GetCacheKey(virtualPath);
        
//     }
        
// }
         #endregion
    }

 

 

 

步骤二:

通过继承VirtualFile类,实现AssemblyResourceVirtualPathProvider的AssemblyResourceVirtualFile,用来提供Resource的Open。

 

VirtualFile代码
     public   class  AssemblyResourceVirtualFile : VirtualFile
    {
        
private   string  AssemblyPath;
        
private   string  ResourceName;

        
public  AssemblyResourceVirtualFile( string  virtualPath,  string  assemblyPath,  string  resourceName)
            : 
base (virtualPath)
        {
            AssemblyPath 
=  assemblyPath; //  Path.Combine(HttpRuntime.BinDirectory, assemblyPath);
            ResourceName  =  resourceName;
        }

        
public   override  System.IO.Stream Open()
        {
            Assembly assembly 
=  Assembly.LoadFrom(AssemblyPath);
            
if  (assembly  !=   null )
            {
                
return  assembly.GetManifestResourceStream(ResourceName);
            }
            
return   null ;
        }
    }

 

 

步骤三:

在Global.asax中注册VirtualPathProvider。

 

Global代码

        
protected   void  Application_Start( object  sender, EventArgs e)
        {
            
string  assemblyPath  =   " WebControlLibrary.dll " ;
            assemblyPath 
=  Path.Combine(HttpRuntime.BinDirectory, assemblyPath);
            AssemblyResourceVirtualPathProvider provider 
=   new  AssemblyResourceVirtualPathProvider( " WebControlDemo " , assemblyPath);

            
// 按链表方式链接注册的VirtualPathProvider。
            HostingEnvironment.RegisterVirtualPathProvider(provider);
        }

 

 

步骤四:

创建Library项目,添加Web User Control,将.ascx文件为嵌入资源。

 

步骤五:

在Web App的页面中使用Web User Control。

 

Page代码
         protected   override   void  OnInit(EventArgs e)
        {
            
// LoadControl中获取对程序集内资源
            
// 当然,可以在aspx中使用:
            
// <%@ Register Src="WebControlDemo/WebControlLibrary.WebUserControl.ascx" TagName="WebUserControl" TagPrefix="uc1" %>
            
// <uc1:WebUserControl id="WebUserControl1_1" runat="server"/>
            WebUserControl1  =   this .LoadControl( " WebControlDemo/WebControlLibrary.WebUserControl.ascx " as  WebUserControl;
            SubWebUserControl1 
=   this .LoadControl( " WebControlDemo/WebControlLibrary.SubDirectory.SubWebUserControl.ascx " as  SubWebUserControl;
            
this .form1.Controls.Add(WebUserControl1);
            
this .form1.Controls.Add(SubWebUserControl1);
            
base .OnInit(e);
        }

 

 

结束语:

通过嵌入资源的联想,可以将JS文件作为嵌入资源,同样可以通过VirtualPathProvider提供访问支持。

 

JS嵌入资源
             // 获取对程序集内资源的 URL 引用 的 虚拟路径方法
            
// 当然,可以在aspx中使用:<script language="javascript" src="WebControlDemo/WebControlLibrary.VirtualPathProvider.js"></script>
             if  ( ! this .ClientScript.IsClientScriptIncludeRegistered(GetType(),  " JS By VirtualPathProvider " ))
            {
                
string  webUrl  =   " WebControlDemo/WebControlLibrary.VirtualPathProvider.js " ;
                
this .ClientScript.RegisterClientScriptInclude(GetType(),  " JS By VirtualPathProvider " , webUrl);
            }

            
// 获取对程序集内资源的 URL 引用 的 一般方法
             if  ( ! this .ClientScript.IsClientScriptIncludeRegistered(GetType(),  " JS By WebResourceUrl " ))
            {
                
string  webUrl  =  Page.ClientScript.GetWebResourceUrl( new  WebUserControl().GetType(),  " WebControlLibrary.WebResourceUrl.js " );
                
this .ClientScript.RegisterClientScriptInclude(GetType(),  " JS By WebResourceUrl " , webUrl);
            }

 

 

 代码示例:http://files.cnblogs.com/xujiaoxiang/WebDemo.zip

你可能感兴趣的:(Provider)