Пользовательский поставщик виртуальных путей в IIS - PullRequest
4 голосов
/ 21 ноября 2010

Какова правильная конфигурация для реализации настраиваемого поставщика виртуальных путей в IIS 7.5?Следующий код работает должным образом при запуске из Visual Studio с использованием сервера разработки ASP.NET, но не загружает образ при запуске из 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

Сайт по умолчанию без изменений конфигурации.

Ответы [ 3 ]

6 голосов
/ 13 декабря 2010

Вот что я нашел, чтобы «исправить» мою проблему.

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()});
5 голосов
/ 14 января 2011

У меня была та же проблема, но Том Кларксон привел меня на правильный путь, он абсолютно прав в том, что вам нужна дополнительная конфигурация, чтобы IIS обслуживал поставщика контента поставщиком виртуальных путей.Я нашел решение здесь

Вот пример web.config-snippet, который, я думаю, будет работать для вас

<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>
1 голос
/ 01 января 2011

Когда FileExists возвращает значение true, оно интерпретируется как «файл существует, IIS может обслуживать его без ASP.NET».Чтобы перейти к следующему этапу фактической загрузки файла через поставщика виртуальных путей, необходимо настроить IIS на использование ASP.NET для обслуживания всех файлов изображений и добавить код в global.asax или обработчик http, который будет использовать вашпоставщик виртуальных путей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...