[英]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.