我有一个ASP.NET MVC应用程序,我正在显示图像。
这些图像可以位于文件系统上或数据库中。这很好,因为我可以在我的图像中使用Url.Action,在我的控制器上调用动作并从相关位置返回图像。
但是,我希望能够支持存储在Amazon S3中的图像。在这种情况下,我不希望我的控制器操作返回图像,而是应该为Amazon S3生成图像URL。
虽然我可以在我的观点中执行此逻辑,例如
<%if(Model.Images [0] .ImageLocation == ImageLocation.AmazonS3){%> //渲染亚马逊图像
我需要先确保图像存在。
基本上我需要将一个大小值传递给我的控制器,以便我可以检查图像是否存在于该大小(无论是在数据库,文件系统还是亚马逊s3中)。一旦我确定图像存在,那么我将URL返回给它。
希望有道理,
本
答案 0 :(得分: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.Images
IEnumerable<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);
}
动作是一种伪代码,但这个想法应该是明确的。
答案 1 :(得分:1)
经过几次迭代后,我提出了一个可行的解决方案,尽管我仍然不相信它是最好的解决方案。
最初我遵循了Anton的建议,并在控制器操作中相应地设置了图片网址。这很简单,使用以下代码:
products.ForEach(p =>
{
p.Images[0].Url = _mediaService.GetImageUrl(p.Images[0], 200);
});
然而,我很快发现这种方法并没有给我所需的灵活性。我经常需要显示不同大小的图像,我不想使用我的模型的属性,例如Product.FullSizeImageUrl,Product.ThumbnailImageUrl。
就“产品”而言,它只知道最初上传的图像。它不需要知道我们如何操作和显示它们,或者我们是否在Amazon S3中缓存它们。
在网络表单中,我可能会使用用户控件来显示产品详细信息,然后使用转发器控件来显示图像,在后面的代码中以编程方式设置图像网址。
我发现在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。
由于 本
答案 2 :(得分:-1)
您可以创建HttpWebRequest
来加载图片。检查响应中的标题,如果它是200表示它成功,否则出现问题。