Después de varias iteraciones he encontrado una solución viable, aunque todavía no estoy convencido de que sea la mejor solución.
Originalmente seguí la sugerencia de Anton y simplemente establecí la url de la imagen en consecuencia dentro de mi acción de controlador. Esto era bastante simple con el siguiente código:
products.ForEach(p =>
{
p.Images[0].Url = _mediaService.GetImageUrl(p.Images[0], 200);
});
Sin embargo, pronto me di cuenta de que este enfoque no me dio la flexibilidad que necesitaba. A menudo necesitaré mostrar imágenes de diferentes tamaños y no quiero usar propiedades de mi modelo para esto, como Product.FullSizeImageUrl, Product.ThumbnailImageUrl.
En lo que respecta al "Producto", solo conoce las imágenes que se cargaron originalmente.No necesita saber cómo manipularlos y mostrarlos, o si los almacenamos en caché en Amazon S3.
En formularios web, podría usar un control de usuario para mostrar detalles del producto y luego usar un control de repetidor para mostrar imágenes, estableciendo las URL de la imagen programáticamente en el código.
He encontrado que el uso de RenderAction en ASP.NET MVC me dio una flexibilidad similar:
Acción controlador:
[ChildActionOnly]
public ActionResult CatalogImage(CatalogImage image, int targetSize)
{
image.Url = _mediaService.GetImageUrl(image, targetSize);
return PartialView(image);
}
Media Service:
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 helper:
public static void RenderCatalogImage(this HtmlHelper helper, CatalogImage src, int size) {
helper.RenderAction("CatalogImage", "Catalog", new { image = src, targetSize = size });
}
Uso:
<%Html.RenderCatalogImage(Model.Images[0], 200); %>
Esto ahora me da la flexibilidad que requiero y apoyará tanto el almacenamiento en caché las imágenes redimensionadas en el disco o guardar en Amazon S3.
Podría hacer con algunos métodos de utilidad de URL para asegurar que la URL de imagen generada sea compatible con SSL/carpetas virtuales. Actualmente estoy usando VirtualPathUtility.
Gracias Ben
Gracias Anton, este es un buen enfoque. Creo que crearé un nuevo ViewModel para esto ya que mi modelo actual es un IList que tiene IList . Parece mejor romper esto en un nuevo modelo de vista donde puedo definir cosas como el tamaño de imagen requerido y tener solo una imagen por producto (que es todo lo que necesito en mi opinión). Voy a publicar mi código una vez hecho. –