2009-08-08 1 views
6

Ecco cosa mi piacerebbe fare. Ho il contenuto che sto scrivendo per una vista. Questo contenuto ha riferimenti alle immagini che sono relativi al documento. Così, per esempio, se sto a guardare il seguente URL:Serve le immagini dallo stesso percorso dell'URL indirizzato in ASP.NET MVC

http://localhost/article/8AB98/ 

Il contenuto potrebbe avere un'immagine nella forma seguente:

<img src="myimage.png" /> 

Questo sarebbe ovviamente causare il browser per interrogare per l'immagine al seguente URL:

http://localhost/article/8AB98/myimage.png 

Tuttavia, a causa del routing mvc, questa immagine non è stata trovata. Sai di un modo semplice in cui posso causare a quell'URL di restituire l'immagine corretta al browser?

si prega di notare: in realtà è importante che il markup restano intatte da quello originale ... questo significa che in qualche modo ri-scrittura URL di immagini in modo da puntare a un'altra cartella di fuori del URL del panorama attuale è purtroppo fuori questione .

Grazie !!

risposta

5

Sto assumendo che quando si dice "in realtà è importante che il markup restano intatte dall'originale" Vuoi dire che

<img src="myimage.png" /> 

è ciò che deve essere resa al browser e quindi è necessario per ingannare il web server a prendere l'URL della richiesta di

http://localhost/article/8AB98/myimage.png 

e utilizzare solo le informazioni per trovare l'immagine giusta, ovunque tu averlo memorizzato, e tornare al browser.

Due opzioni vengono in mente, ma è difficile sapere quale consigliare perché non è stato detto dove vengono memorizzate le immagini.

Opzione 1 - URL Rewriter

acquistare una copia del ISAPI_Rewrite ed avere tutti gli URL che soddisfano i criteri di cui sopra riscritti in modo da andare a prendere l'immagine ovunque essi si trovino. Altro su ISAPI_Rewrite here.

Opzione 2 - Custom HttpHandler

Si potrebbe scrivere un HttpHandler mappato a tutte le richieste di file PNG che analizza l'URL della richiesta e fa quello che deve fare per trovare l'immagine, per poi tornare al flusso di risposta . Lo svantaggio di questo è che dovresti dire a IIS di mappare tutte le richieste PNG per passare attraverso aspnet_isapi.dll, il che potrebbe essere un fiasco per le prestazioni.

Non sono ancora sicuro di aver compreso correttamente il problema, ma spero che questo aiuti. In bocca al lupo.

+0

Non ho usato esattamente le tue due opzioni, ma questa era in definitiva la soluzione che lo risolse :-) I ' Pubblicherò un'altra risposta alla domanda con i dettagli –

1

Un modo per farlo sarebbe quello di mettere in un IgnoreRoute per i file di immagine:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("article/{ArticleID}/{name}.png"); 
    ... 
6

È possibile utilizzare il metodo() Url.Content.

<img src="<%= Url.Content("~/images/myimage.png") %>" /> 

Questo risolverà l'url dalla radice dell'applicazione.

+1

Sarei tentato di scrivere anche un helper in modo da poter avere solo Html.Image ("~/images/myimage. png "," myAltText "); E il tuo metodo di aiuto dovrebbe restituire fondamentalmente il codice di Phil. –

+0

Ciao Phil ... cambiando l'URL da "myimage.png", a ciò che url.content restituisce non è possibile, perché il markup del contenuto non è mio per cambiare. A parte questo, ho effettivamente bisogno di questo markup () da rendere al browser (come @thinkzig menzionato) –

-1

Ho finito per utilizzare la soluzione di @ thinkzig, anche se in un modo leggermente diverso. Usando il FileContent dall'assembly MVC Futures, ho appena aggiunto un altro percorso per gestire le immagini.

routes.MapRoute("Image", "article/{id}/{image}", new { controller = "Article", action = "Image" }); 
routes.MapRoute("Article", "article/{id}", new { controller = "Article", action = "Index" }); 

Questo nuovo metodo di azione costruisce semplicemente il percorso del file in base al nome articleID e immagine:

public ActionResult Image(string id, string image) 
{ 
    string articlePath = Server.MapPath("~/views/article/"); 
    string filePath = Path.Combine(articlePath, string.Format("{0}/{1}", id, image)); 
    return this.File(filePath, "image"); 
} 

C'era un'altra piccola cosa che ho dovuto fare i conti con. Se l'utente accede all'articolo senza una barra finale (http://localhost/article/8AB98), il browser pensa che l'ID articolo è il file e tenta di trovare la cartella dell'immagine errata (http://localhost/article/img.png).

Fortunatamente in questo caso, mvc indirizza la richiesta all'azione Articolo con il nome dell'immagine come parametro "id", quindi posso semplicemente cercare un "." nell'ID e quindi utilizzare l'azione Image normale per elaborarlo.

nell'articolo azione:

if (id.Contains(".")) 
{ 
    return RedirectToImage(id); 
} 

E poi il codice redirecttoimage, che capisce l'ID e il nome del file

private ActionResult RedirectToImage(string id) 
{ 
    if (Request.UrlReferrer == null) 
    { 
     return Content("invalid request"); 
    } 

    var referrer = Request.UrlReferrer.ToString(); 
    if (referrer.Contains("?")) 
    { 
     referrer = referrer.Split('?')[0]; 
    } 

    var realId = Path.GetFileName(referrer); 
    return this.Image(realId, id); 
} 

Noterete che mi baso sulla URL di riferimento per ottenere l'ID dell'articolo reale. Se l'utente prova a fare clic con il pulsante destro sull'immagine (se visualizzato senza la barra finale) e sceglie "Apri immagine in una nuova scheda", non ho modo di sapere quale sia l'ID dell'articolo, quindi restituisco solo una "richiesta non valida" stringa all'utente. Va bene perché in realtà non sto cercando di supportare quegli utenti :-)