2010-02-01 42 views
5

Tôi có ứng dụng ASP.NET MVC nơi tôi hiển thị hình ảnh.ASP.NET MVC URL tạo ảnh động được tạo

Những hình ảnh này có thể được đặt trên hệ thống tệp hoặc bên trong cơ sở dữ liệu. Điều này là tốt như tôi có thể sử dụng Url.Action trong hình ảnh của tôi, gọi hành động trên bộ điều khiển của tôi và trả lại hình ảnh từ vị trí có liên quan.

Tuy nhiên, tôi muốn có thể hỗ trợ hình ảnh được lưu trữ trong Amazon S3. Trong trường hợp này, tôi không muốn hành động điều khiển của mình trả lại hình ảnh, thay vào đó nó sẽ tạo một URL hình ảnh cho Amazon S3.

Mặc dù tôi chỉ có thể thực hiện logic này trong chế độ xem của tôi, ví dụ:

<% if (Model.Images [0] .ImageLocation == ImageLocation.AmazonS3) {%> // làm amazon ảnh

tôi cần phải đảm bảo rằng hình ảnh tồn tại đầu tiên.

Về cơ bản tôi cần chuyển giá trị kích thước cho bộ điều khiển của mình để tôi có thể kiểm tra xem hình ảnh có tồn tại ở kích thước đó không (trong cơ sở dữ liệu, hệ thống tệp hoặc amazon s3). Khi tôi chắc chắn rằng hình ảnh tồn tại, sau đó tôi trả lại URL cho nó.

Hy vọng rằng sẽ có ý nghĩa,

Bến

Trả lời

2

Thử cách tiếp cận sau.

Lớp mô hình cho thẻ hình ảnh.

public class ImageModel 
{ 
    public String Source { get; set; } 
    public String Title { get; set; } 
} 

Helper Xem

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(); 
} 

với Model.Images loại IEnumerable<ImageModel>

...  
<%= Html.Image(Model.Images[0].Source, Model.Images[0].Title) %> 

Action

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); 
} 

Một hành động là một loại mã giả Tuy nhiên, ý tưởng phải rõ ràng.

+0

Cảm ơn Anton, đây là cách tiếp cận tốt. Tôi nghĩ rằng tôi sẽ tạo một ViewModel mới cho điều này vì mô hình hiện tại của tôi là một IList có IList . Có vẻ tốt hơn để chia nhỏ điều này thành mô hình chế độ xem mới, nơi tôi có thể xác định những thứ như kích thước hình ảnh yêu cầu và chỉ có một hình ảnh cho mỗi sản phẩm (tất cả những gì tôi cần trong chế độ xem của mình). Tôi sẽ đăng mã của mình sau khi hoàn tất. –

-1

Bạn có thể tạo một HttpWebRequest để tải hình ảnh. Kiểm tra các tiêu đề trong phản ứng, nếu nó là 200 có nghĩa là nó đã thành công, nếu không một cái gì đó đã đi sai.

+0

Hi, yêu cầu chính là tôi có thể xây dựng các URL động dựa trên nơi hình ảnh "nên" được đặt. Tôi không cần phải sử dụng một HttpWebRequest để kiểm tra hình ảnh tồn tại, tôi có thể sử dụng System.IO.File.Exists cho điều này hoặc kiểm tra thùng S3 của Amazon. Cảm ơn Ben –

1

Sau một vài lần lặp lại, tôi đã đưa ra một giải pháp khả thi, mặc dù tôi vẫn chưa thuyết phục được giải pháp tốt nhất của nó.

Ban đầu tôi đã theo đề xuất của Anton và chỉ đặt url hình ảnh tương ứng trong hành động điều khiển của tôi. Điều này đủ đơn giản với mã sau:

 products.ForEach(p => 
     { 
      p.Images[0].Url = _mediaService.GetImageUrl(p.Images[0], 200); 
     }); 

Tuy nhiên, tôi sớm nhận thấy rằng phương pháp này không mang lại sự linh hoạt mà tôi cần. Thường thì tôi sẽ cần phải hiển thị hình ảnh của các kích cỡ khác nhau và tôi không muốn sử dụng các thuộc tính của mô hình của tôi cho điều này như Product.FullSizeImageUrl, Product.ThumbnailImageUrl.

Theo như "Sản phẩm" có liên quan, nó chỉ biết về những hình ảnh được tải lên ban đầu.Nó không cần phải biết cách chúng ta thao tác và hiển thị chúng, hay chúng ta đang lưu chúng trong Amazon S3.

Trong biểu mẫu web, tôi có thể sử dụng điều khiển người dùng để hiển thị chi tiết sản phẩm và sau đó sử dụng điều khiển bộ lặp để hiển thị hình ảnh, đặt url hình ảnh lập trình theo mã phía sau.

tôi thấy rằng việc sử dụng các RenderAction trong ASP.NET MVC đã cho tôi sự linh hoạt tương tự:

điều khiển hành động:

[ChildActionOnly] 
    public ActionResult CatalogImage(CatalogImage image, int targetSize) 
    { 
     image.Url = _mediaService.GetImageUrl(image, targetSize); 
     return PartialView(image); 
    } 

Dịch vụ Truyền thông:

  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 }); 
    } 

Cách sử dụng:

<%Html.RenderCatalogImage(Model.Images[0], 200); %> 

Điều này giờ đây mang lại cho tôi sự linh hoạt mà tôi yêu cầu và sẽ hỗ trợ cả lưu vào bộ nhớ đệm hoặc lưu vào Amazon S3.

Có thể thực hiện với một số phương pháp tiện ích url để đảm bảo rằng URL hình ảnh được tạo hỗ trợ các thư mục SSL/ảo - Tôi hiện đang sử dụng VirtualPathUtility.

Cảm ơn Bến

Các vấn đề liên quan