Cómo enrutar imágenes usando ASP.Net ¿Enrutamiento MVC?


He actualizado mi sitio para usar ASP.Net MVC de tradicional ASP.Net formularios web. Estoy usando el enrutamiento MVC para redirigir las solicitudes de edad .páginas aspx a su nuevo Controlador/Acción equivalente:

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

Esto funciona muy bien para las páginas porque se asignan directamente a un controlador y una acción. Sin embargo, mi problema son las solicitudes de imágenes - no estoy seguro de cómo redirigir esas solicitudes entrantes.

Necesito redirigir las solicitudes entrantes para http://www.domain.com/graphics/image.png a http://www.domain.com/content/images/image.png.

¿Cuál es la sintaxis correcta cuando se usa el método .MapRoute()?

Author: womp, 2009-07-18

2 answers

No puede hacer esto "fuera de la caja" con el marco MVC. Recuerde que hay una diferencia entre Enrutamiento y reescritura de URL. El enrutamiento es asignar cada solicitud a un recurso, y el recurso esperado es una pieza de código.

Sin embargo, la flexibilidad del framework MVC le permite hacer esto sin ningún problema real. Por defecto, cuando llamas a routes.MapRoute(), está manejando la solicitud con una instancia de MvcRouteHandler(). Puede crear un controlador personalizado para manejar su imagen URL.

  1. Cree una clase, tal vez llamada ImageRouteHandler, que implemente IRouteHandler.

  2. Agregue la asignación a su aplicación de la siguiente manera:

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

  3. Eso es.

Así es como se ve tu clase 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 "";
        }
    }
}
 48
Author: womp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-16 15:24:45

Si tuviera que hacer esto usando ASP.NET 3.5 Sp1 WebForms tendría que crear un ImageHTTPHandler separado que implemente IHttpHandler para manejar la respuesta. Esencialmente todo lo que tendría que hacer es poner el código que está actualmente en el método GetHttpHandler en el método ProcessRequest de ImageHttpHandler. También movería el método GetContentType a la clase ImageHTTPHandler. También agregue una variable para contener el nombre del archivo.

Entonces tu clase ImageRouteHanlder parece:

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

            return new ImageHttpHandler(filename);

        }
    } 

Y tu clase ImageHttpHandler se vería como:

 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
    }
 6
Author: awright18,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-13 16:58:33