2012-02-06 84 views
4

我知道如何從MVC控制器返回一個圖像,但是想知道從MVC控制器返回CDN中的圖像是否會破壞爲圖像使用CDN的目的。將使用以下代碼導致Web服務器託管從CDN下載的Web應用程序,然後將其提供給用戶從Web服務器下載?圖像是否下載過兩次,一次是從CDN到Web服務器,然後是Web服務器到用戶?如果這樣比直接在網絡服務器上託管圖像更糟?或者是隻下載一次圖像,直接從CDN下載到最終用戶?ASP.NET MVC:從控制器返回CDN圖像

如何從MVC控制器返回圖像,同時利用CDN的優勢?

public ActionResult Thumb(int id) 
    { 
     //process 
     var file = Server.MapPath(" path to image in the CDN "); 
     //do your stuff 
     return File(file, "image/jpg", Path.GetFileName(file)); 
    } 

回答

8

在你的控制器動作,您需要執行一個HTTP請求從遠程服務器上獲取的圖像:

public ActionResult Thumb(int id) 
{ 
    using (var client = new WebClient()) 
    { 
     byte[] image = client.DownloadData("http://cdn.foo.com/myimage.jpg"); 
     return File(image, "image/jpg"); 
    } 
} 

然後:

<img src="@Url.Action("Thumb")" alt="" /> 

顯然現在映像下載兩次。一旦從CDN進入控制器,一次從客戶端進入。這完全違背了該控制器行動的目的,你可以直接從CDN引用圖像:

<img src="http://cdn.foo.com/myimage.jpg" alt="" /> 

這顯然假定客戶端訪問CDN。

當然,如果您的控制器操作不僅僅是從CDN獲取圖像並將其流式傳輸到客戶端,例如從CDN獲取圖像並調整其大小,那麼您應該採取第一種方法。

1

Server.MapPath用於映射圖像的物理路徑,它不會爲CDN圖像做任何事情,因爲它不在物理路徑本地存在。不,你不想返回一個文件。

您的HTML只會引用<img>標記中的CDN圖像。即

<img src="http://mycdn.com/image" /> 
1

不要從控制器返回實際圖像。這是更糟的,因爲然後你下載它兩次(CDN - >服務器 - >客戶端)。您根本不需要Thumb操作。

如果您需要生成控制器中CDN文件的鏈接,那麼只需在視圖的CDN鏈接模型中添加一個屬性並將其設置在控制器中即可。

創建你的控制器的鏈接:

public ActionController SomeAction(int id){ 
    var model = new SomeActionViewModel(); 

    model.CDNLink = // do some stuff to generate CDN Link and set them on the model; 
    return View(model); 
} 

後來終於把它在你看來

<img src="@Model.CDNLink" alt=""/> 
1

我使用URL重寫模塊2.0 outboundRules。 更改響應html Img(圖片),鏈接(css),腳本(js)標記url。

URL Rewrite Module 2.0 Configuration Reference : URL Rewrite Module 2 : URL Rewrite Module : The Official Microsoft IIS Site

電流響應

... 
<img src="/images/photo1.jpg" /> 
<img src="/images/photo2.jpg" /> 
... 

集的web.config urlrewrite配置。

<rewrite> 
    <outboundRules> 
     <rule name="cdn" preCondition="html" enabled="true"> 
      <match filterByTags="Img, Link, Script" 
         pattern="^/(images|csc|js)/(.*)" /> 
      <action type="Rewrite" value="//cdn.local/{R:1}/{R:2}" /> 
     </rule> 
     <preConditions> 
      <preCondition name="html"> 
       <add input="{RESPONSE_CONTENT_TYPE}" pattern="text/html" /> 
      </preCondition> 
     </preConditions> 
    </outboundRules> 
</rewrite> 

重寫響應

... 
<img src="//cdn.local/images/photo1.jpg" /> 
<img src="//cdn.local/images/photo2.jpg" /> 
... 

希望這有助於。

1

CDN配置可能有所不同,但最常見的設置是CDN服務器將充當您的服務器(「原始服務器」)的大型分佈式代理。

CDN不關心你如何傳送你的內容。您可以告訴它通過URL,內容類型或其他因素代理內容。

所以你的情況,假設的內容,一旦從控制器傳送,也不會改變,可以設置如下:

  1. 請求CDN服務器
  2. CDN服務器請求到控制器方法在源服務器上
  3. 控制器方法生成內容
  4. CDN後續請求緩存內容
  5. CDN返回內容
  6. 通過URL返回相同內容的後續請求從CDN返回

返回靜態內容時最重要的因素是您使用的URL結構。

CDN確實(可以)在緩存和過期方面關心響應頭,但如果您可以正確地使用URL來提供獨特內容(例如解決版本問題),最好避免這種情況。

如果您嘗試保護內容,CDN也可以這樣做,但通常需要特定於CDN的技術。

1

假設您需要先進行一些計算來找出資源,例如根據某個ID進行查找,以解析CDN網址。您絕對不應該使用Web客戶端並將圖像下載到字節數組中。如果你不得不下載文件,它本質上變成了一種不穩定的資源,你需要決定如何處理它,使用一個斷路器,可能沒有緩存,你需要緩衝它,以便它也不會使用很多記憶。

在這種情況下,您最好根據用例解決url並使用重定向301/302。

public ActionResult Thumb(int id) 
{ 
    //resolve url 
    var file = " path to image in the CDN "; 
    //redirect permanent 
    return RedirectPermanent(file); 
    //OR redirect 
    return Redirect(file); 
}