2

我有一个大型遗留应用程序,我想将我们所有的图像移动到 CDN。

目前,我们所有的图像都驻留在应用程序根目录下,因此路径都像"~/Images/MyImage.jpg." 由于我们系统的要求,如果要在 CDN 中存在给定图像,我必须在运行时确定给定图像的完整 URL。这使我们可以严格控制版本控制、缓存等。逐个图像地更改代码将是一个非常漫长、乏味且容易出错的过程。

我想做的是能够连接到 ASP.NET 中的某些机制,我可以在其中决定如何解析图像的波浪号。这将允许我们所有现有代码保持原样,并且图像将在运行时定向到 CDN。

我发现了一些关于VirtualPathProviders的提及,这听起来像是我正在寻找的东西,但是当我测试它时,唯一传递给CombineVirtualPaths函数的路径是以 . 结尾的路径.ASPX, .ASCX, and .MASTER

谁能帮我找到一个干净、低风险的选择?

基本上,我需要在我的应用程序中将“~/images/myimage.jpg”作为“http://mycdnhost.com/myimage.jpg”呈现给浏览器的任何地方。这将完全避免浏览器向我们的服务器发送图像请求。

4

1 回答 1

3

使用 IIS 路由

提供来自不同站点或服务器的静态内容。您的 Web 应用程序部署在多台服务器上,动态 Web 内容位于一个站点或服务器上,而所有静态内容位于不同的站点或服务器上。您可以将 URL 重写模块与 IIS 应用程序请求路由模块一起使用,将所有对静态文件的请求转发到不同的服务器,同时为来自当前服务器的所有动态网页请求提供服务。这样,ASP.NET 路由仅用于动态 Web 内容,而不评估静态内容的任何 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 路径。首先,您需要将图像文件的文件扩展名映射到 IIS 中的 aspnet_isapi。然后,添加一个为这些文件扩展名执行 url 重定向的 httpmodule。例如,在模块的 beginrequest 方法中:

    void context_BeginRequest(object sender, 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 生命周期的开销,因为我们必须在将整个页面发送到客户端之前拦截整个页面。

使用控制适配器

如果您只想处理图像控件以劫持图像控件渲染方法并有选择地更改 cdn url 的路径,您应该尝试使用 ASP.Net 控件适配器。这种方法风险较小且可拆卸。

 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>

问候。

于 2012-04-25T12:16:45.410 回答