簡體   English   中英

ASP.NET中圖像的CDN

[英]CDN for Images in ASP.NET

我正在將Web應用程序中的所有圖像都移到CDN上,但是我希望能夠輕松地打開或關閉CDN,而不必對圖像的路徑進行硬編碼。

我的第一個想法是為圖像擴展添加一個HttpHandler,該擴展取決於web.config中的變量(類似)是從服務器還是從CDN提供圖像。 但是,盡管稍加說明,但我認為我基本上已將其排除在外,因為它將導致ASP.NET處理每個單個圖像的請求,從而增加開銷,並且實際上可能會完全減輕使用CDN的好處。

一種替代方法是,由於我的所有頁面都繼承自基頁類,因此我可以在基類中創建一個函數,該函數根據web.config變量確定從哪個路徑提供文件。 然后,我將在標記中執行以下操作:

<img src='<%= GetImagePath()/image.png' />

我認為這可能是我最終必須要做的,但是對我來說似乎有點笨拙。 我也預見到了舊的.NET錯誤,由於“ <%=”解決方案可能會起作用,因此由於“ <%=”而無法修改控件集合的問題。

關於如何執行此操作的任何想法或想法?

您已經HttpHandler基於預優化假設編寫HttpHandler的想法。 我將重新審視它,並一定會編寫一個簡單的HttpHandler並對其進行測試。 您可能會發現您的Page方法解決方案甚至可能更慢,特別是如果您涉及ASP預處理器。

HttpHandlers非常接近金屬-IIS將請求提交給ASP.Net的開銷很小。 這將是一個比您提議的方案更為優雅的解決方案,並且可能更具擴展性,我願意打賭-更快。

您是否考慮過一種更簡單的方法?

如果您的頁面全部繼承自基類,則可以向CDN(或您要關閉CDN的本地服務器)公開包含前綴URL的屬性。 然后,將前綴URL存儲在web.config中就變得很簡單了:

public string PrependURLPath() {
 get { return ConfigurationManager.AppSettings["ImagePrependURL"].ToString(); }
}

在您的<appSettings/>元素中,您可以簡單地選擇前綴URL,例如:

http://my.cdn.com/user/

要么:

http://my.own.server.com/images/

很簡單!

然后,您將可以按照示例對圖像引用進行編碼,但是可以調用基本屬性來公開所需的路徑:

<img src='<%= this.BasePage.PrependURLPath() + [YourImagePath.png] %>'/>

我同意通過內聯調用設置圖像源是很麻煩的,但是您可以按照其他人的建議進行操作,然后遍歷頁面上的圖像控件,並隨即更改前綴URL。

即使您的頁面當前僅從System.Web.UI.Page繼承,創建您自己的繼承System.Web.Page的基類,然后在解決方案中對所有其余頁面進行查找/替換也很簡單。

希望這可以幫助。

在這里很晚才稱重,但我自己一直在尋找類似的解決方案。 搜索谷歌以理智檢查我做了什么。 沒有考慮HttpHandler方法,我只是擴展了ASP.net Image控件:

public class Img : Image
{
    public Img()
    {
        RelativePath = false;
    }

    public bool RelativePath { get; set; }

    public override string ImageUrl
    {
        get
        {
            if (RelativePath)
                return base.ImageUrl;

            return "http://some.configurable-value.com" + base.ImageUrl;
        } 
        set { base.ImageUrl = value; }
    }
}

它雖然很粗糙而且已經准備好了,但是它可以正常工作:)顯然,它應該依賴於一些可配置的值而不是字符串文字,但這並不是什么大的改變

如果使用標簽顯示圖像,則可以創建控件適配器,這些控件使您可以更改.net控件的呈現方式或通用更改它們的方法,如下所示:

using System.Web.UI.WebControls.Adapters;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ExampleCode
{
    public class ImageAdapter : WebControlAdapter
    {
        private bool UseCdn
        {
            get { return true; } // Get value from config or anywhere else
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            Image image = (Image)Control;

            if (UseCdn)
            {
                // If using relative urls for images may need to handle ~
                image.ImageUrl = String.Format("{0}/{1}", "CDN URL", image.ImageUrl);
            }
         }
      }
 }

然后將瀏覽器文件添加到Web項目中的App_Browsers文件夾中,如下所示:

<browsers>
    <browser refID="Default">
      <controlAdapters>
        <adapter
          controlType="System.Web.UI.WebControls.Image"
          adapterType="ExampleCode.ImageAdapter"
          />
      </controlAdapters>
    </browser>
</browsers>

您可以循環所有控件並在基類的prerender事件中更改圖像url ...

HTTP處理程序方法的優點在於它非常可重用和可配置:您可以根據位置確定要處理的img路徑-假設它們所處的結構對此有所幫助。

可能的缺點是圖像文件擴展名(.jpg,.png等)不會自動傳遞到asp.net管道。 您可以輕松地配置IIS來做到這一點-但您需要對IIS進行一定程度的控制-因此,如果您在共享主機環境中,則可能不是一個選擇。

我必須解決您的問題,另一個是要解決的問題,那就是我不想在開發過程中從CDN中獲取資源,而只是在將網站部署在生產服務器上時才可以。 為了解決這個問題,我開發了一個ExpressionBuilder,它僅在生產中添加CDN URL。

<asp:Image ImageUrl="<%$ CdnUrl:/images/myimage.png %>" runat="server" />

在先前的代碼中,CDN URL僅在生產中被添加。

namespace IdeaR.Web.Compilation
{
[ExpressionPrefix("CdnUrl")]
public class CdnUrlExpressionBuilder : ExpressionBuilder
{
    public static object GetCdnUrl(string expression, Type target, string entry)
    {
        var retvalue = expression;
        var productionUri = new Uri("http://www.myproductionurl.com",
            UriKind.Absolute);
        var currentUri = HttpContext.Current.Request.Url;
        var cdnUrl = "http://cdn.mycdn.com";

        // If this is a production website URL
        if (currentUri.Scheme == productionUri.Scheme &&
            currentUri.Host == productionUri.Host)
            retvalue = cdnUrl + expression;

        return retvalue;
    }

    public override CodeExpression GetCodeExpression(BoundPropertyEntry entry,
        object parsedData, ExpressionBuilderContext context)
    {
        var componentType = entry.DeclaringType;
        var expressionArray = new CodeExpression[3]
        {
            new CodePrimitiveExpression(entry.Expression.Trim()),
            new CodeTypeOfExpression(componentType),
            new CodePrimitiveExpression(entry.Name)
        };

        var descriptor = TypeDescriptor.GetProperties(componentType)
            [entry.PropertyInfo.Name];
        return new CodeCastExpression(descriptor.PropertyType,
            new CodeMethodInvokeExpression(
                new CodeTypeReferenceExpression(GetType()),
                "GetCdnUrl", expressionArray));
    }       
}
}

有關更多信息,我寫了一篇關於如何在生產中使用CDN而不是在開發過程中使用CDN的文章。

我將使用@Rhys方法進行圖像控制。

大多數時候,我嘗試使用背景圖像CSS而不是使用圖像控件。

之后,我將css和圖像都上傳到雲中,並且可以正常工作的相對路徑。

看起來還沒有一個可以接受的答案,所以這是我的建議。 我在處理透明修改URL時遇到了類似的問題(到另一端,但是我也考慮將其用於CDN支持)。

這是一個舊的過濾器/模塊,但稍作調整即可很好地滿足我的需求: http : //www.paraesthesia.com/archive/2007/12/14/urlabsolutifiermodule---convert-urls-in-asp.net -輸出到absolute.aspx

您可以做的是制作一個響應過濾器,並將其與httpmodule掛鈎(就像這個絕對值)。 如果使用此模塊+響應過濾器,則可以通過修改源以替換主機名/為所有URL加上前綴以使用CDN來實現所需的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM