2010-11-20 131 views
4

在IIS 7.5中實現自定義虛擬路徑提供程序的正確配置是什麼?以下代碼在從Visual Studio使用ASP.NET Development Server運行時按預期工作,但在從IIS運行時不加載映像。IIS中的自定義虛擬路徑提供程序

.NET 4.0的項目文件

CustomVirtualPathProvider.zip - SkyDrive的文件

的Web.config

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

Default.aspx的

<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <title>Virtual Path Provider</title> 
    </head> 
    <body> 
     <img src="Box.png" /> 
    </body> 
</html> 

的Global.asax

public class Global : System.Web.HttpApplication 
{ 
    void Application_Start(object sender, EventArgs e) 
    { 
     System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new WebApplication1.CustomVirtualPathProvider()); 
    } 
} 

CustomVirtualFile.cs

public class CustomVirtualFile : System.Web.Hosting.VirtualFile 
{ 
    private string _VirtualPath; 

    public CustomVirtualFile(string virtualPath) : base(virtualPath) 
    { 
     _VirtualPath = virtualPath.Replace("/", string.Empty); 
    } 

    public override Stream Open() 
    { 
     string ImageFile = 
      System.IO.Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, @"Crazy\Image\Path", _VirtualPath); 
     return System.IO.File.Open(ImageFile, FileMode.Open, FileAccess.Read); 
    } 
} 

CustomVirtualPathProvider.cs

public class CustomVirtualPathProvider : System.Web.Hosting.VirtualPathProvider 
{ 
    Collection<string> ImageTypes; 

    public CustomVirtualPathProvider() : base() 
    { 
     ImageTypes = new Collection<string>(); 
     ImageTypes.Add(".PNG"); 
     ImageTypes.Add(".GIF"); 
    } 

    public override bool FileExists(string virtualPath) 
    { 
     if (IsImage(virtualPath)) 
     { 
      return true; 
     } 
     return base.FileExists(virtualPath); 
    } 

    public override System.Web.Hosting.VirtualFile GetFile(string virtualPath) 
    { 
     if (IsImage(virtualPath)) 
     { 
      return new CustomVirtualFile(virtualPath); 
     } 
     return base.GetFile(virtualPath); 
    } 

    private bool IsImage(string file) 
    { 
     return ImageTypes.IndexOf(file.ToUpperInvariant().Substring(file.Length - 4, 4)) > -1; 
    } 
} 

文件系統

\Crazy\Image\Path\Box.png 

IIS配置

默認的站點沒有配置更改。

+0

你有試圖調試並打入你的代碼嗎?是調用Application_Start,那麼你的CustomVirtualPathProvider構造函數或它的任何方法呢? – 2010-12-13 20:51:11

回答

5

這是我發現「修復」我的問題。

http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/

簡單:

HostingEnviornment明確地忽略了預編譯的網站虛擬路徑提供。您可以通過使用反射調用省略此檢查的內部版本來規避此限制。因此,而不是調用

HostingEnviornment.RegisterVirtualPathProvider(new EmbeddedViewVirtualPathProvider(); 

調用這個代替:

typeof(HostingEnvironment).GetMethod("RegisterVirtualPathProviderInternal", 
     BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.NonPublic) 
    .Invoke(null, new object[] {new EmbeddedViewPathProvider()}); 
+0

這意味着......它還沒有答案。請添加評論,而不是:) – 2010-12-13 20:51:41

+0

泡利:是的,我應該留下評論。很多道歉! – 2010-12-13 20:54:22

1

當FILEEXISTS返回true,它被解釋爲 「有一個文件存在,IIS可以成爲它沒有ASP.NET」。要實際下載文件以通過虛擬路徑提供程序的下一步,您需要將IIS設置爲使用ASP.NET來提供所有圖像文件,並在global.asax或http處理程序中添加代碼,以便使用您的虛擬路徑提供者。

5

我有同樣的問題,但湯姆克拉克森帶領我走上正軌,他絕對正確,因爲您需要額外的配置才能使IIS通過虛擬路徑提供程序爲內容提供者提供服務。我發現了一個解決方案here

這裏是一個web示例。配置 - 摘錄,我認爲會爲你工作

<system.web> 
    <httpHandlers> 
    <add path="*.png" verb="*" type="System.Web.StaticFileHandler" validate="true" /> 
    <add path="*.gif" verb="*" type="System.Web.StaticFileHandler" validate="true" /> 
    </httpHandlers> 
</system.web> 

你也可以註冊一個「通配符的HttpHandler」在一個特殊的位置(例如「/ MyVirtualFiles」),如果你的虛擬路徑提供用於許多不同的,這可能是有用的文件類型。

<location path="MyVirtualFiles"> 
    <system.web> 
    <httpHandlers> 
     <add path="*" verb="*" type="System.Web.StaticFileHandler" validate="true" /> 
    </httpHandlers> 
    </system.web> 
</location>