【问题标题】:How do I route images using ASP.Net MVC routing?如何使用 ASP.Net MVC 路由来路由图像?
【发布时间】:2010-11-11 21:52:13
【问题描述】:

我将我的网站升级为使用传统 ASP.Net 网络表单中的 ASP.Net MVC。我正在使用 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() 方法时的正确语法是什么?

【问题讨论】:

    标签: c# asp.net asp.net-mvc routing url-rewriting


    【解决方案1】:

    您不能使用 MVC 框架“开箱即用”地做到这一点。请记住,路由和 URL 重写之间是有区别的。路由就是把每一个请求映射到一个资源上,期望的资源就是一段代码。

    但是 - MVC 框架的灵活性让您可以毫无问题地做到这一点。默认情况下,当您调用routes.MapRoute() 时,它会使用MvcRouteHandler() 的实例处理请求。您可以构建一个 custom 处理程序来处理您的图像 url。

    1. 创建一个类,可能称为 ImageRouteHandler,实现IRouteHandler

    2. 像这样将映射添加到您的应用中:

      routes.Add("ImagesRoute", new Route("graphics/{filename}",
      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 "";
            }
        }
    }
    

    【讨论】:

    • 可以在没有 Response.End 方法的情况下工作吗?只是认为在每个图像请求上抛出异常(来自 Response.End)并不是最好的方法......
    • Kamarey 说得好。 Rick Strahl 有一篇关于此的博客文章,结论是确实没有完美的方法来处理它。在这里查看:west-wind.com/WebLog/posts/368975.aspx
    • 我读了你的文章...干得好。它工作得很好,设置起来非常容易,不到 15 分钟
    • +1 来自我 - 无需太多调整即可工作,并帮助我解决了一个我认为可能需要数天......在短短一个小时内完成的问题。
    • @womp - 我是 MVC 的新手,只是想澄清一件事,我们不能使用 IgnoreRoute() 忽略 .png 文件,以便由 ASP.NET 路由引擎处理请求,而不是处理请求,然后路由到物理位置的文件。
    【解决方案2】:

    如果您要使用 ASP.NET 3.5 Sp1 WebForms 来执行此操作,则必须创建一个单独的 ImageHTTPHandler 来实现 IHttpHandler 来处理响应。基本上,您所要做的就是将当前在 GetHttpHandler 方法中的代码放入 ImageHttpHandler 的 ProcessRequest 方法中。我还将 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
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-27
      • 2010-10-18
      • 2013-03-12
      • 1970-01-01
      • 2023-04-03
      • 2014-09-11
      • 2011-03-28
      相关资源
      最近更新 更多