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 :-)
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 –