2017-08-29 55 views
-3

我在Web服務器上獲得了像{sku_number} .jpg這樣的圖像。現在我希望爲每個訪問者提供一個像{sku_number} foo.jpg這樣的圖像的文件名,而無需重命名Web服務器上的文件。設置帶有額外信息的圖像的虛擬路徑

這是可能的和如何?

+0

請問您可以添加文件的示例,如何將它們保存在網絡服務器上以及如何讓相同的文件在網絡中看起來像? –

+0

他們就像123456789.jpg,我想123456789_TitleOfTheProduct.jpg。但我不想重命名所有文件,因爲標題可能會隨時更改。我想這個文件名是「虛擬的」。 –

回答

0

如果我正確理解你,然後其中一個選項是HTTP Handler

public class ImageHttpHandler : IHttpHandler 
{ 

    public bool IsReusable 
    { 
     get { return false; } 
    } 
    protected RequestContext RequestContext { get; set; } 

    public void ProcessRequest(HttpContext context) 
    { 
     AdvertType type; 
     var url = context.Request.Url.ToString(); 
     //TODO: get ID and extension from url 123456789_TitleOfTheProduct.jpg 
     var path = "yourpathtoimgfolder/id.extension" 
     //Get binary data 

     context.Response.ContentType = "image/png"; 
     context.Response.BinaryWrite(bytes); 
    } 
} 

然後在system.webServer web.config中註冊它 - >處理

<add name="YourName" verb="*" path="virtual/folder/*" type="Namespace.ImageHttpHandler, Your.Assembly.With.Handler, Version=1.0.0.0, Culture=neutral" preCondition="managedHandler" /> 
+0

這似乎只是解決方案的一個方面。當發出請求時,我們必須在磁盤上找到物理文件。但是,這不是解決方案來爲img-Tag獲取正確的Url。 –

0

Reference

Url.Content helper方法需要av虛擬內容路徑到您的文件並返回一個URL來訪問您的站點中的文件。您不應該將物理目錄位置傳遞給該位置。

您可能會考慮將圖像保存在您的網絡應用程序中。創建一個名爲「Images」的目錄,然後你可以安全地使用Url.Content方法。

例如,

@foreach (var imgPath in Directory.GetFiles(Server.MapPath(Url.Content("~/Images/")))) 
{ 
    <img src="@Url.Content("~/Images/"+ @Path.GetFileName(imgPath))" /> 
} 

,或者如果你確實需要在一些地方保存應用程序根目錄外的圖像(例如:「C:\ TEMP \圖像或網絡位置),你可能會考慮創建一個這需要的文件名操作方法,從位置讀取該文件,並返回爲圖像。

public ActionResult GetImg(string id) 
{ 
    var path = [email protected]"C:\temp\images\{id}.png"; 
    var bytes = System.IO.File.ReadAllBytes(path); 
    return File(bytes, "image/png"); 
} 

現在,你只需要調用這個終點,並用其作爲圖像的src屬性。

@foreach (var imgPath in Directory.GetFiles(@"C:\temp\images", "*.*")) 
{ 
    <img src="@Url.Action("GetImg",new {id=Path.GetFileNameWithoutExtension(imgPath)})" /> 
} 

以上是一個簡單的解決方案,我硬編碼它返回PNG文件。你可以更新它以更靈活(增加一個參數來接受文件擴展名)

注意:我個人更喜歡在剃鬚刀文件中保留最小的C#。我喜歡將C#代碼(所有這些Directory.GetFiles行)移動到GET操作,並通過視圖模型/視圖包(根據需要)將圖像名稱列表傳遞給視圖。

+0

您的第一個解決方案不起作用。我需要磁盤上的文件,而不需要將它們包含在解決方案中。 –

0

您可以創建一個簡單的控制器來處理這些請求。

[RoutePrefix("products/images")] 
public class ProductImagesController : Controller { 
    [HttpGet] 
    [Route("{sku_number:long}_{title}.{extension}", Name = "ProductSkuImage")]//Matches GET products/images/123456789_TitleOfTheProduct.jpg 
    public ActionResult Get(long sku_number, string title, string extension) { 
     var fileStorePath = Server.MapPath("~/images"); 
     var fileName = string.Format("{0}.{1}", sku_number, extension); 
     var path = Path.Combine(fileStorePath, fileName); 
     if (System.IO.File.Exists(path)) { 
      var mimeType = MimeMapping.GetMimeMapping(fileName); 
      var downloadName = string.Format("{0}_{1}.{2}",sku_number,title,extension); 
      return File(path, mimeType, downloadName); 
     } 
     return HttpNotFound(); 
    } 
} 

只是作爲一個簡單的自我解釋的例子,上述可以重構,以提供更多的靈活性。例如,不用從磁盤加載文件,sku可以用來從另一個數據存儲中獲取文件,如數據庫或Web服務。

從視圖中調用的

<a href="@Url.RoutUrl("ProductSkuImage", new { sku_number=123456789 , title = "TitleOfTheProduct" , extension="jpg" })" >TitleOfTheProduct</a> 

會產生

<a href="http://localhost/products/images/123456789_TitleOfTheProduct.jpg">TitleOfTheProduct</a>  
+0

看起來很有希望。讓我先測試一下。我會爲img-Tag獲得正確的Url嗎? –

+0

@TimurZanagar查看示例添加到回答 – Nkosi

1

我會建議從僞造的圖像與原始圖像返回302,它會允許你的Web服務器仍能正常緩存資產,而不必在每次請求資產時從文件系統進行非常低效的讀取/寫入操作。NET級別,同時仍然用欺騙路徑掩蓋DOM中的路徑(儘管如果這是一個問題,原始路徑將是可見的)。

確認302將滿足您的特定需求。

否則,你會希望基本上模擬資產緩存的IIS管道,這可能很粗糙。

+0

這不起作用。這種變化是爲了SEO的目的。我們的搜索引擎優化人員和谷歌圖片文檔說,你必須在圖像文件中指定產品的標題,而不僅僅是在alt-Tag中。 –

+0

確定很好奇那裏的目的 - 是301s會導致重命名和302s不會攜帶「SEO果汁」的問題。 所以,請記住,您可能需要複製IIS的緩存功能,而不是像下面的其他建議一樣進行懶讀/寫操作。不幸的是,我完全不知道IIS如何確定這一點,所以我不能建議類似的緩存設置。 – StrangeWill