2009-07-18 3 views
34

Ich habe meine Site aktualisiert, um ASP.Net MVC aus herkömmlichen ASP.Net-Webformularen zu verwenden. Ich verwende die MVC Routing-Anfragen für alte ASPX-Seiten zu ihrer neuen Controller/Aktion entspricht umleiten:Wie route ich Bilder mithilfe von ASP.Net MVC-Routing?

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

Dies funktioniert hervorragend für Seiten, weil sie direkt mit einem Controller und die Aktion zuzuordnen. Mein Problem sind jedoch Anfragen nach Bildern - ich bin mir nicht sicher, wie ich diese eingehenden Anfragen umleiten soll.

Ich muss eingehende Anfragen für http://www.domain.com/graphics/image.png zu http://www.domain.com/content/images/image.png umleiten.

Wie lautet die korrekte Syntax bei der Verwendung der Methode .MapRoute()?

Antwort

48

Sie können dies nicht "out of the box" mit dem MVC-Framework tun. Denken Sie daran, dass es einen Unterschied zwischen Routing und URL-Neuschreiben gibt. Das Routing ordnet jede Anfrage einer Ressource zu und die erwartete Ressource ist ein Stück Code.

Allerdings - die Flexibilität des MVC-Framework ermöglicht es Ihnen, dies ohne echtes Problem zu tun. Wenn Sie aufrufen, verarbeitet es standardmäßig die Anforderung mit einer Instanz MvcRouteHandler(). Sie können einen benutzerdefinierten-Handler erstellen, um Ihre Bild-URLs zu verarbeiten.

  1. Erstellen Sie eine Klasse, vielleicht ImageRouteHandler genannt, die IRouteHandler implementiert.

  2. die Zuordnung zu Ihrer App wie folgt hinzufügen:

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

  3. Das ist es.

Hier ist, was Ihre IRouteHandler Klasse wie folgt aussieht:

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, das perfekt gearbeitet. Danke! –

+0

kein Problem, froh, dass es geholfen hat. – womp

+0

Kann dies ohne Response.End-Methode funktionieren? Denken Sie nur, dass eine Ausnahme (von Response.End) auf jede Bildanforderung zu werfen ist nicht der beste Weg ... – Kamarey

6

Wenn Sie dies mit ASP.NET 3.5 Sp1 WebForms zu tun wären, würde man einen separaten ImageHTTPHandler erstellen, die IHttpHandler implementiert die Antwort zu handhaben . Im Wesentlichen müssen Sie nur den Code, der sich derzeit in der GetHttpHandler-Methode befindet, in die ProcessRequest-Methode von ImageHttpHandler einfügen. Ich würde auch die GetContentType-Methode in die ImageHTTPHandler-Klasse verschieben. Fügen Sie außerdem eine Variable hinzu, um den Namen der Datei zu speichern.

Dann Ihre ImageRouteHanlder Klasse wie folgt aussieht:

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

      return new ImageHttpHandler(filename); 

     } 
    } 

und Sie ImageHttpHandler Klasse würde wie folgt aussehen:

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 
    } 
Verwandte Themen