2009-07-18 39 views
34

Tôi đã nâng cấp trang web của mình để sử dụng ASP.Net MVC từ các biểu mẫu web ASP.Net truyền thống. Tôi đang sử dụng định tuyến MVC để chuyển hướng yêu cầu về trang .aspx cũ sang mới Controller/Action tương đương của họ:Làm cách nào để định tuyến hình ảnh bằng cách sử dụng định tuyến ASP.Net MVC?

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

này đang làm việc tuyệt vời cho trang này vì chúng xạ trực tiếp đến một bộ điều khiển và hành động. Tuy nhiên, vấn đề của tôi là yêu cầu hình ảnh - Tôi không chắc chắn cách chuyển hướng các yêu cầu đến đó.

Tôi cần chuyển hướng các yêu cầu đến cho http://www.domain.com/graphics/image.png đến http://www.domain.com/content/images/image.png.

Cú pháp chính xác khi sử dụng phương pháp .MapRoute() là gì?

Trả lời

48

Bạn không thể làm điều này "ngoài hộp" với khung MVC. Hãy nhớ rằng có sự khác biệt giữa Định tuyến và viết lại URL. Định tuyến là ánh xạ mọi yêu cầu đến một tài nguyên và tài nguyên dự kiến ​​là một đoạn mã.

Tuy nhiên - tính linh hoạt của khung MVC cho phép bạn thực hiện việc này mà không gặp phải vấn đề thực sự nào. Theo mặc định, khi bạn gọi routes.MapRoute(), nó xử lý yêu cầu với một phiên bản MvcRouteHandler(). Bạn có thể tạo một bộ xử lý tùy chỉnh tùy chỉnh để xử lý url hình ảnh của mình.

  1. Tạo lớp học, có thể gọi là ImageRouteHandler, thực hiện IRouteHandler.

  2. Thêm bản đồ để ứng dụng của bạn như thế này:

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

  3. Vậy là xong.

Đây là những gì lớp IRouteHandler của bạn trông giống như:

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, mà làm việc một cách hoàn hảo. cảm ơn bạn! –

+0

không có vấn đề, vui vì nó đã giúp. – womp

+0

Điều này có thể hoạt động mà không có phương thức Response.End không? Chỉ cần nghĩ rằng ném một ngoại lệ (từ Response.End) vào mỗi yêu cầu hình ảnh không phải là cách tốt nhất ... – Kamarey

6

Nếu bạn đã làm điều này bằng ASP.NET 3.5 Sp1 WebForms bạn sẽ phải tạo ra một ImageHTTPHandler riêng biệt mà thực hiện IHttpHandler để xử lý các phản ứng . Về cơ bản tất cả những gì bạn phải làm là đặt mã hiện đang trong phương thức GetHttpHandler vào phương thức ProcessRequest của ImageHttpHandler. Tôi cũng sẽ di chuyển phương thức GetContentType vào lớp ImageHTTPHandler. Cũng thêm một biến để giữ tên của tập tin.

Sau đó, lớp ImageRouteHanlder của bạn trông giống như:

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

      return new ImageHttpHandler(filename); 

     } 
    } 

và bạn lớp ImageHttpHandler sẽ trông như thế:

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 
    } 
Các vấn đề liên quan