Jak trasować obrazy za pomocą ASP.Net routing MVC?

Ulepszyłem moją stronę do użycia ASP.Net MVC z tradycyjnego ASP.Net webforms. Używam routingu MVC do przekierowywania wniosków o stare .strony aspx do ich nowego odpowiednika kontrolera/akcji:

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

To działa świetnie dla stron, ponieważ mapują one bezpośrednio do kontrolera i akcji. Jednak moim problemem są prośby o obrazy - nie jestem pewien, jak przekierować te przychodzące żądania.

Muszę przekierować przychodzące żądania dla http://www.domain.com/graphics/image.png do http://www.domain.com/content/images/image.png .

Jaka jest prawidłowa składnia przy użyciu metody .MapRoute()?

Author: womp, 2009-07-18

2 answers

Nie możesz zrobić tego "po wyjęciu z pudełka" z frameworkiem MVC. Pamiętaj, że istnieje różnica między routingiem a przepisywaniem adresów URL. Routing to mapowanie każdego żądania do zasobu, a oczekiwany zasób to fragment kodu.

Jednak - elastyczność frameworku MVC pozwala to zrobić bez realnego problemu. Domyślnie wywołanie routes.MapRoute() obsługuje żądanie z instancją MvcRouteHandler(). Możesz zbudować custom handler do obsługi Twojego obrazu URL.

  1. Tworzy klasę, nazywaną ImageRouteHandler, która implementuje IRouteHandler.

  2. Dodaj mapowanie do aplikacji w następujący sposób:

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

  3. To wszystko.

Oto jak wygląda twoja IRouteHandler klasa:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-16 15:24:45

Jeśli miałbyś to zrobić używając ASP.NET 3.5 SP1 WebForms trzeba by utworzyć oddzielny ImageHTTPHandler, który implementuje IHttpHandler do obsługi odpowiedzi. Zasadniczo wszystko, co musisz zrobić, to umieścić kod, który jest obecnie w metodzie GetHttpHandler w metodzie ProcessRequest ImageHttpHandler. Chciałbym również przenieść metodę GetContentType do klasy ImageHTTPHandler. Dodaj również zmienną do przechowywania nazwy pliku.

Then your ImageRouteHanlder class wygląda jak:

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

            return new ImageHttpHandler(filename);

        }
    } 

A Ty wyobrażasz sobie, że Klasa wygląda tak:

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-13 16:58:33