Nach mehreren Iterationen habe ich eine praktikable Lösung gefunden, obwohl ich immer noch nicht überzeugt bin, dass es die beste Lösung ist.
Ursprünglich folgte ich dem Vorschlag von Anton und setzte die Bild-URL entsprechend in meine Controller-Aktion. Das war einfach genug, um mit dem folgenden Code:
products.ForEach(p =>
{
p.Images[0].Url = _mediaService.GetImageUrl(p.Images[0], 200);
});
Aber ich fand bald, dass dieser Ansatz mir nicht gab die Flexibilität, die ich brauchte. Oft muss ich Bilder in verschiedenen Größen anzeigen, und ich möchte dafür keine Eigenschaften meines Modells verwenden, z. B. Product.FullSizeImageUrl, Product.ThumbnailImageUrl.
Soweit "Produkt" betroffen ist, weiß es nur über die Bilder, die ursprünglich hochgeladen wurden.Es muss nicht wissen, wie wir sie manipulieren und anzeigen oder ob wir sie in Amazon S3 zwischenspeichern.
In Webformularen kann ich ein Benutzersteuerelement verwenden, um Produktdetails anzuzeigen, und dann ein Repeater-Steuerelement verwenden, um Bilder anzuzeigen und die Bild-URLs programmatisch im Code festzulegen.
fand ich, dass die Verwendung von Render in ASP.NET MVC gab mir eine ähnliche Flexibilität:
Controller Aktion:
[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-Helfer:
public static void RenderCatalogImage(this HtmlHelper helper, CatalogImage src, int size) {
helper.RenderAction("CatalogImage", "Catalog", new { image = src, targetSize = size });
}
Verbrauch:
<%Html.RenderCatalogImage(Model.Images[0], 200); %>
Die jetzt gibt mir die Flexibilität, die wir benötigen und sowohl das Zwischenspeichern die verkleinerten Bilder auf der Festplatte oder das Speichern auf Amazon S3 unterstützen.
Könnte mit einigen URL-Hilfsmethoden tun, um sicherzustellen, dass die generierte Bild-URL SSL/virtuelle Ordner unterstützt - ich verwende derzeit VirtualPathUtility.
Dank Ben
Dank Anton, das ist eine gute Vorgehensweise. Ich denke, ich werde ein neues ViewModel dafür erstellen, da mein aktuelles Modell ein IList mit IList ist. Scheint besser, dies in ein neues Ansichtsmodell zu zerlegen, wo ich Dinge wie die benötigte Bildgröße definieren kann und nur ein einziges Bild pro Produkt habe (was ich aus meiner Sicht brauche). Ich poste meinen Code einmal fertig. –