2009-07-18 14 views
34

Ho aggiornato il mio sito per utilizzare ASP.Net MVC dai tradizionali webform ASP.Net. Sto utilizzando il percorso MVC per reindirizzare le richieste di pagine aspx vecchi per il loro nuovo controller/azione equivalente:Come si instradano le immagini utilizzando il routing ASP.Net MVC?

 routes.MapRoute(
      "OldPage", 
      "oldpage.aspx", 
      new { controller = "NewController", action = "NewAction", id = "" } 
     ); 

Questo sta lavorando molto per le pagine, perché associati direttamente a un controller e di azione. Tuttavia, il mio problema sono le richieste di immagini - Non sono sicuro di come reindirizzare quelle richieste in arrivo.

Devo reindirizzare le richieste in entrata per http://www.domain.com/graphics/image.png a http://www.domain.com/content/images/image.png.

Qual è la sintassi corretta quando si utilizza il metodo .MapRoute()?

risposta

48

Non è possibile eseguire questa operazione "out of the box" con il framework MVC. Ricorda che c'è una differenza tra Routing e riscrittura degli URL. Il routing sta mappando ogni richiesta a una risorsa e la risorsa prevista è un pezzo di codice.

Tuttavia, la flessibilità del framework MVC consente di farlo senza alcun problema reale. Per impostazione predefinita, quando si chiama routes.MapRoute(), gestisce la richiesta con un'istanza di MvcRouteHandler(). Puoi gestire un handler personalizzato per gestire i tuoi URL immagine.

  1. creare una classe, forse chiamato ImageRouteHandler, che implementa IRouteHandler.

  2. aggiungere il mapping per la vostra applicazione in questo modo:

    routes.Add("ImagesRoute", new Route("graphics/{filename}",
    new ImageRouteHandler()));

  3. Questo è tutto.

Ecco cosa la classe IRouteHandler assomiglia:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Web; 
using System.Web.Compilation; 
using System.Web.Routing; 
using System.Web.UI; 

namespace MvcApplication1 
{ 
    public class ImageRouteHandler : IRouteHandler 
    { 
     public IHttpHandler GetHttpHandler(RequestContext requestContext) 
     { 
      string filename = requestContext.RouteData.Values["filename"] as string; 

      if (string.IsNullOrEmpty(filename)) 
      { 
       // return a 404 HttpHandler here 
      } 
      else 
      { 
       requestContext.HttpContext.Response.Clear(); 
       requestContext.HttpContext.Response.ContentType = GetContentType(requestContext.HttpContext.Request.Url.ToString()); 

       // find physical path to image here. 
       string filepath = requestContext.HttpContext.Server.MapPath("~/test.jpg"); 

       requestContext.HttpContext.Response.WriteFile(filepath); 
       requestContext.HttpContext.Response.End(); 

      } 
      return null; 
     } 

     private static string GetContentType(String path) 
     { 
      switch (Path.GetExtension(path)) 
      { 
       case ".bmp": return "Image/bmp"; 
       case ".gif": return "Image/gif"; 
       case ".jpg": return "Image/jpeg"; 
       case ".png": return "Image/png"; 
       default: break; 
      } 
      return ""; 
     } 
    } 
} 
+0

wow, che ha funzionato perfettamente. grazie! –

+0

nessun problema, lieto che abbia aiutato. – womp

+0

Può funzionare senza Response.End metodo? Basti pensare che lanciare un'eccezione (da Response.End) su ogni richiesta di immagine non è il modo migliore ... – Kamarey

6

Se si dovesse fare questo usando ASP.NET 3.5 WebForms Sp1 si dovrebbe creare un ImageHTTPHandler separato che implementa IHttpHandler per gestire la risposta . In sostanza, tutto ciò che dovresti fare è inserire il codice attualmente nel metodo GetHttpHandler nel metodo ProcessRequest di ImageHttpHandler. Sposterei anche il metodo GetContentType nella classe ImageHTTPHandler. Aggiungere anche una variabile per contenere il nome del file.

Poi la classe ImageRouteHanlder assomiglia:

public class ImageRouteHandler:IRouteHandler 
    { 
     public IHttpHandler GetHttpHandler(RequestContext requestContext) 
     { 
      string filename = requestContext.RouteData.Values["filename"] as string; 

      return new ImageHttpHandler(filename); 

     } 
    } 

e classe ImageHttpHandler sarà simile:

public class ImageHttpHandler:IHttpHandler 
    { 
     private string _fileName; 

     public ImageHttpHandler(string filename) 
     { 
      _fileName = filename; 
     } 

     #region IHttpHandler Members 

     public bool IsReusable 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public void ProcessRequest(HttpContext context) 
     { 
      if (string.IsNullOrEmpty(_fileName)) 
      { 
       context.Response.Clear(); 
       context.Response.StatusCode = 404; 
       context.Response.End(); 
      } 
      else 
      { 
       context.Response.Clear(); 
       context.Response.ContentType = GetContentType(context.Request.Url.ToString()); 

       // find physical path to image here. 
       string filepath = context.Server.MapPath("~/images/" + _fileName); 

       context.Response.WriteFile(filepath); 
       context.Response.End(); 
      } 

     } 

     private static string GetContentType(String path) 
     { 
      switch (Path.GetExtension(path)) 
      { 
       case ".bmp": return "Image/bmp"; 
       case ".gif": return "Image/gif"; 
       case ".jpg": return "Image/jpeg"; 
       case ".png": return "Image/png"; 
       default: break; 
      } 
      return ""; 
     } 

     #endregion 
    } 
Problemi correlati