經過幾次迭代後,我想出了一個可行的解決方案,但我仍然不相信它是最好的解決方案。
本來我遵循安東的建議,只是在我的控制器操作中設置圖像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。
感謝 本
謝謝安東,這是很好的方法。我想我會爲此創建一個新的ViewModel,因爲我目前的模型是IList,它具有IList 。 似乎更好地將其分解爲新的視圖模型,在該模型中,我可以定義所需圖像大小等事物,並且每個產品只有一個圖像(這正是我所需要的)。 我會在完成後發佈我的代碼。 –
2010-02-01 18:40:26