Переопределить разрешение тильды (~) ASP.NET только для изображений

У меня есть большое устаревшее приложение, и я хотел бы переместить все наши изображения в CDN.

В настоящее время все наши изображения находятся в корневом каталоге самого приложения, поэтому все пути похожи на "~/Images/MyImage.jpg.". Из-за требований нашей системы я ДОЛЖЕН определить полный URL-адрес для данного изображения во время выполнения, если оно должно жить в CDN. Это дает нам жесткий контроль над версиями, кэшированием и т. д. Внесение изменений в код изображение за изображением будет очень долгим, утомительным и подверженным ошибкам процессом.

Что я хотел бы сделать, так это иметь возможность подключиться к некоторому механизму в ASP.NET, где я могу решить, как я хочу разрешить тильду для изображения. Это позволит оставить весь наш существующий код как есть, а изображения будут направляться в CDN во время выполнения.

Я нашел несколько упоминаний о VirtualPathProviders, которые звучали так, как будто это то, что я искал, но когда я тестировал его, в функцию CombineVirtualPaths передавались только пути: пути, оканчивающиеся на .ASPX, .ASCX, and .MASTER.

Может ли кто-нибудь помочь мне найти чистый вариант с низким уровнем риска для этого?

По сути, мне нужно, чтобы где-нибудь в моем приложении, где у меня есть "~/images/myimage.jpg", отображаемый в браузере как "http://mycdnhost.com/myimage.jpg". Это позволит браузеру вообще не отправлять запрос на наш сервер для изображения.


person Brent Miller    schedule 25.04.2012    source источник
comment
Какую версию IIS вы используете?   -  person Antonio Bakula    schedule 25.04.2012
comment
Посмотрите здесь возможное решение: stackoverflow.com/ вопросы/4350571/   -  person Soliah    schedule 16.05.2012


Ответы (1)


Использование маршрутизации IIS

Обслуживание статического контента с другого сайта или сервера. Ваше веб-приложение развертывается на нескольких серверах таким образом, что динамическое веб-содержимое находится на одном сайте или сервере, а все статическое содержимое — на другом сайте или сервере. Вы можете использовать модуль перезаписи URL-адресов вместе с модулем маршрутизации запросов приложений IIS, чтобы перенаправлять все запросы на статические файлы на другой сервер, одновременно обслуживая все запросы на динамические веб-страницы с текущего сервера. Таким образом, маршрутизация ASP.NET используется только для динамического веб-контента и не оценивает никакие URL-адреса для статического контента.

В следующем примере показано правило перезаписи URL-адреса, которое можно использовать для этого сценария.

<rewrite>
    <rules>
        <rule name="Forward to static file server">
            <match url="^.+\.(?:jpg|bmp|gif)$" />
            <action type="Rewrite" url="http://static_file_server/{R:0}" />
        </rule>
    </rules>
</rewrite>

Дополнительные сведения см. по адресу: http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/.

Использование HttpModule

  1. Вам следует попробовать создать HttpModule, который перехватывает запрос изображения и пытается перенаправить его на ваш путь CDN. Во-первых, вам нужно сопоставить расширение файла изображения с aspnet_isapi в IIS. Затем добавьте httpmodule, который выполняет перенаправление URL-адресов для этих расширений файлов. Например, в методе beginrequest модуля:

    void context_BeginRequest (отправитель объекта, EventArgs e) { if (request.url.endwith .jpg/.png ...) перенаправить на путь относительно корневой папки. }

  2. Другой вариант использования httpmodule — перехватить отображаемый html и заменить URL-адреса изображений с помощью регулярного выражения, чтобы они указывали на CDN. здесь вы можете увидеть, как это работает http://shoaibsheikh.blogspot.com/2012/05/change-image-url-in-aspnet-using.html

Этот метод увеличивает нагрузку на жизненный цикл asp.net, потому что нам придется перехватывать всю страницу до ее отправки клиенту.

Использование адаптеров управления

Вам следует попробовать адаптеры управления ASP.Net, если вы хотите обрабатывать только элементы управления изображениями для захвата метода рендеринга управления изображениями и выборочно изменить путь к URL-адресу cdn. Этот метод менее рискованный и съемный.

 public class CDNImageControlAdapter : ControlAdapter
    {
        protected override void Render(HtmlTextWriter writer)
        {
            Image img = this.Control as Image;
            if (img == null)
            {
                base.Render(writer);
                return;
            }

            if (img.ImageUrl.Length > 0)
            {
                // Let the HyperLink render its begin tag
                img.RenderBeginTag(writer);

                Image image = new Image();

                if (img.ImageUrl.IndexOf("~") == 0)
                {
                    img.ImageUrl = (img.ImageUrl.Replace("~", "http://mycdn.com/images/"));

                }

                img.RenderControl(writer);
            }
            else
            {
                // HyperLink.RenderContents handles a couple of other
                // cases if its ImageUrl property hasn't been set. We
                // delegate to that behavior here.
                base.Render(writer);
            }
        }
    }

и добавьте файл All.broswer в папку App_Browsers приложения

<!--
    You can find existing browser definitions at
    <windir>\Microsoft.NET\Framework\<ver>\CONFIG\Browsers
-->
<browsers>
  <browser id="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.WebControls.Image" adapterType="CDNImageControlAdapter, MyWebApplication" />
    </controlAdapters>
  </browser>
</browsers>

С уважением.

person Shoaib Shaikh    schedule 25.04.2012
comment
Это решение не было бы идеальным для меня, потому что оно касалось бы только элемента управления Image. Я хочу указать ВЕЗДЕ, что путь к изображению указан с помощью тильды. Это может быть любое количество свойств в любом количестве элементов управления WebControl, HtmlControls или сторонних элементов управления. Мне нужно универсальное средство. - person Brent Miller; 03.05.2012
comment
хорошо, я думал, что вас беспокоит только элемент управления изображением. В вашем случае вам следует попробовать использовать httpmodule, но для этого вам нужно будет сопоставить расширения изображений, которые будут передаваться через управляемый модуль isapi, что может привести к накладным расходам на процесс asp.net на сервере, но это вариант. - person Shoaib Shaikh; 04.05.2012
comment
Спасибо за ваше обновление, но оно по-прежнему не соответствует моим требованиям. Я обновил свой вопрос, чтобы, надеюсь, внести ясность. Ваше предложение требует, чтобы запрос изображения сначала поступал на наш сервер, а затем перенаправлялся в другое место. Нам нужно, чтобы разметка, которая изначально отображается на сервере, имела путь к изображению, указывающий на совершенно другой хост. - person Brent Miller; 04.05.2012
comment
я добавил еще один вариант с использованием маршрутизации IIS, если вы можете его применить. Проверь это - person Shoaib Shaikh; 06.05.2012
comment
Опять же, проблема в том, что каждое предложенное вами решение перезаписывает путь, когда сервер получает запрос на изображение. Мне нужно манипулировать путем к изображению до того, как путь будет отправлен в браузер для начала. - person Brent Miller; 09.05.2012
comment
Я добавил еще одну опцию httpmodule, которая будет перехватывать html-разметку вашего кода и изменять URL-адреса изображений с помощью регулярных выражений. shoaibsheikh.blogspot.com/2012/05/ - person Shoaib Shaikh; 10.05.2012