2010-02-01 160 views
5

我有一個ASP.NET MVC應用程序,我正在顯示圖像。ASP.NET MVC動態生成的圖像URL

這些圖像可能位於文件系統或數據庫內。這很好,因爲我可以在圖像中使用Url.Action,在我的控制器上調用該操作並從相關位置返回圖像。

但是,我希望能夠支持存儲在Amazon S3中的圖像。在這種情況下,我不希望我的控制器操作返回圖像,而應該爲Amazon S3生成圖像URL。

雖然我可以在我的視圖內執行這個邏輯,例如

<%如果(Model.Images [0] == .ImageLocation ImageLocation.AmazonS3){%> //渲染亞馬遜圖像

我需要確保圖像第一存在。

本質上,我需要傳遞一個大小值到我的控制器,以便我可以檢查圖像是否以該大小存在(無論是在數據庫,文件系統還是亞馬遜S3中)。一旦我確信圖像存在,然後我將URL返回給它。

希望是有道理的,

回答

2

請嘗試以下方法。

圖像標籤的模型類。

public class ImageModel 
{ 
    public String Source { get; set; } 
    public String Title { get; set; } 
} 

助手

public static String Image(this HtmlHelper helper, String source, String title) 
{ 
    var builder = new TagBuilder("img"); 
    builder.MergeAttribute("src", source); 
    builder.MergeAttribute("title", title); 
    return builder.ToString(); 
} 

查看與類型的Model.ImagesIEnumerable<ImageModel>

...  
<%= Html.Image(Model.Images[0].Source, Model.Images[0].Title) %> 

行動

public ActionResult ActionName(/*whatever*/) 
{ 
    // ... 
    var model = ...; 
    //... 

    var model0 = ImageModel(); 
    if (Image0.ImageLocation == ImageLocation.AmazonS3) 
     model0.Source = "an amazon url"; 
    else 
     model0.Source = Url.Action("GetImageFromDatabaseOrFileSystem", "MyController", new { Id = Image0.Id }); 
    model0.Title = "some title"; 
    model.Images.Add(model0); 
    // ... 
    return View(model); 
} 

的行動是一種僞代碼但是這個想法應該清楚。

+0

謝謝安東,這是很好的方法。我想我會爲此創建一個新的ViewModel,因爲我目前的模型是IList ,它具有IList 。 似乎更好地將其分解爲新的視圖模型,在該模型中,我可以定義所需圖像大小等事物,並且每個產品只有一個圖像(這正是我所需要的)。 我會在完成後發佈我的代碼。 – 2010-02-01 18:40:26

-1

您可以創建一個HttpWebRequest加載圖像。檢查響應中的標題,如果它是200表示成功,否則出現問題。

+0

嗨,主要的要求是,我能夠構造URL動態基礎上,在圖像「應當」來定位。我不需要使用HttpWebRequest來檢查映像是否存在,我可以使用System.IO.File.Exists進行此操作或檢查Amazon S3存儲桶。 謝謝 本 – 2010-02-01 15:48:50

1

經過幾次迭代後,我想出了一個可行的解決方案,但我仍然不相信它是最好的解決方案。

本來我遵循安東的建議,只是在我的控制器操作中設置圖像URL。這很簡單,下面的代碼:

 products.ForEach(p => 
     { 
      p.Images[0].Url = _mediaService.GetImageUrl(p.Images[0], 200); 
     }); 

但是,我很快發現這種方法沒有給我我需要的靈活性。通常我需要顯示不同大小的圖像,而且我不想使用我的模型的屬性,例如Product.FullSizeImageUrl,Product.ThumbnailImageUrl。

就「產品」而言,它只知道最初上傳的圖像。它不需要知道我們如何操作和顯示它們,或者我們是否將它們緩存在Amazon S3中。

在網絡表單中,我可能會使用用戶控件來顯示產品詳細信息,然後使用中繼器控件來顯示圖像,在代碼後面以編程方式設置圖像url。

我發現,在ASP.NET MVC中使用的的RenderAction給了我類似的靈活性:

控制器動作:

[ChildActionOnly] 
    public ActionResult CatalogImage(CatalogImage image, int targetSize) 
    { 
     image.Url = _mediaService.GetImageUrl(image, targetSize); 
     return PartialView(image); 
    } 

媒體服務:

  public MediaCacheLocation CacheLocation { get; set; } 

    public string GetImageUrl(CatalogImage image, int targetSize) 
    { 
     string imageUrl; 

     // check image exists 
     // if not exist, load original image from store (fs or db) 
     // resize and cache to relevant cache location 

     switch (this.CacheLocation) { 
      case MediaCacheLocation.FileSystem: 
       imageUrl = GetFileSystemImageUrl(image, targetSize); 
       break; 
      case MediaCacheLocation.AmazonS3: 
       imageUrl = GetAmazonS3ImageUrl(image, targetSize); 
       break; 
      default: 
       imageUrl = GetDefaultImageUrl(); 
       break; 
     } 

     return imageUrl; 
    } 

的HTML幫助:

 public static void RenderCatalogImage(this HtmlHelper helper, CatalogImage src, int size) { 
     helper.RenderAction("CatalogImage", "Catalog", new { image = src, targetSize = size }); 
    } 

用法:

<%Html.RenderCatalogImage(Model.Images[0], 200); %> 

現在,這給了我,我需要的靈活性,並支持緩存縮放後的圖像到磁盤或保存到Amazon S3。

可以使用一些url實用程序方法來確保生成的圖像URL支持SSL /虛擬文件夾 - 我目前正在使用VirtualPathUtility。

感謝 本