ASP.NET MVC动态生成的图像URL

时间:2010-02-01 15:23:16

标签: asp.net-mvc model-view-controller

我有一个ASP.NET MVC应用程序,我正在显示图像。

这些图像可以位于文件系统上或数据库中。这很好,因为我可以在我的图像中使用Url.Action,在我的控制器上调用动作并从相关位置返回图像。

但是,我希望能够支持存储在Amazon S3中的图像。在这种情况下,我不希望我的控制器操作返回图像,而是应该为Amazon S3生成图像URL。

虽然我可以在我的观点中执行此逻辑,例如

<%if(Model.Images [0] .ImageLocation == ImageLocation.AmazonS3){%> //渲染亚马逊图像

我需要先确保图像存在。

基本上我需要将一个大小值传递给我的控制器,以便我可以检查图像是否存在于该大小(无论是在数据库,文件系统还是亚马逊s3中)。一旦我确定图像存在,那么我将URL返回给它。

希望有道理,

3 个答案:

答案 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表示它成功,否则出现问题。