Как маршрутизировать изображения с использованием ASP.Net MVC? - PullRequest
35 голосов
/ 18 июля 2009

Я обновил свой сайт, чтобы использовать ASP.Net MVC из традиционных веб-форм ASP.Net. Я использую маршрутизацию MVC для перенаправления запросов на старые страницы .aspx на их новый эквивалент Controller / Action:

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

Это прекрасно работает для страниц, потому что они отображаются непосредственно на контроллер и действие. Однако моя проблема - запросы на изображения - я не уверен, как перенаправить эти входящие запросы.

Мне нужно перенаправить входящие запросы на http://www.domain.com/graphics/image.png на http://www.domain.com/content/images/image.png.

Какой правильный синтаксис при использовании метода .MapRoute()?

Ответы [ 2 ]

50 голосов
/ 18 июля 2009

Вы не можете сделать это "из коробки" с платформой MVC. Помните, что есть разница между маршрутизацией и перезаписью URL. Маршрутизация отображает каждый запрос к ресурсу, а ожидаемый ресурс представляет собой фрагмент кода.

Однако - гибкость инфраструктуры MVC позволяет вам делать это без особых проблем. По умолчанию, когда вы вызываете routes.MapRoute(), он обрабатывает запрос с экземпляром MvcRouteHandler(). Вы можете создать пользовательский обработчик для обработки URL-адресов ваших изображений.

  1. Создайте класс, возможно, с именем ImageRouteHandler, который реализует IRouteHandler.

  2. Добавьте отображение в ваше приложение, как это:

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

  3. Вот и все.

Вот как выглядит ваш IRouteHandler класс:

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 "";
        }
    }
}
6 голосов
/ 13 ноября 2009

Если бы вы делали это, используя ASP.NET 3.5 Sp1 WebForms, вам пришлось бы создать отдельный ImageHTTPHandler, который реализует IHttpHandler для обработки ответа. По сути, все, что вам нужно сделать, это поместить код, который в настоящее время находится в методе GetHttpHandler, в метод ProcessRequest вашего ImageHttpHandler. Я также переместил бы метод GetContentType в класс ImageHTTPHandler. Также добавьте переменную для хранения имени файла.

Тогда ваш класс ImageRouteHanlder будет выглядеть так:

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

            return new ImageHttpHandler(filename);

        }
    } 

и ваш класс ImageHttpHandler будет выглядеть так:

 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
    }
...