经过几次迭代后,我想出了一个可行的解决方案,但我仍然不相信它是最好的解决方案。
本来我遵循安东的建议,只是在我的控制器操作中设置图像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