C# 如何通过ASP.NET路由传送图像?

C# 如何通过ASP.NET路由传送图像?,c#,url-routing,asp.net-routing,C#,Url Routing,Asp.net Routing,我想创建一个动态缩略图大小调整器,以便您可以使用以下URL获取大小调整后的图像: http://server/images/image.jpg?width=320&height=240 我试着设置一条这样的路线: routes.MapRoute(null, "{filename}", new { controller = "Image", action = "Resize" }); 但是,如果URL上存在该文件,ASP.

我想创建一个动态缩略图大小调整器,以便您可以使用以下URL获取大小调整后的图像:

http://server/images/image.jpg?width=320&height=240
我试着设置一条这样的路线:

routes.MapRoute(null,
                "{filename}",
                new { controller = "Image", action = "Resize" });

但是,如果URL上存在该文件,ASP.NET将绕过路由,只返回该文件。如何强制ASP.NET路由图像,而不是返回磁盘上的内容?

这就是ASP.NET路由的工作原理,没有其他解决方案。。。如果要拦截对现有文件的请求,必须使用“重写”

更新


看起来我的扳机有点太快了。似乎有一个属性可以设置,它允许您甚至为现有文件强制路由

RouteCollection.RouteExistingFiles属性


获取或设置一个值,该值指示ASP.NET路由是否应处理与现有文件匹配的URL。如果ASP.NET路由处理所有请求,即使是与现有文件匹配的请求,则为True;否则,错误。默认值为false。

为什么不使用操作来执行此操作?控制器的操作可以流式返回图像。否则,典型的方法(比如ASPX)是处理程序或处理程序工厂侦听文件扩展名并相应地进行处理。或者使用URL重写来重写请求中的URL。

最简单的方法是通过控制器路由所有图像,并将图像存储在单独的位置

routes.MapRoute("Images",
            "/images/{filename}",
            new { controller = "Image", action = "Resize" });

/sitebase/images/image.jpg         //public image location
/sitebase/content/images/image.jpg //real image location
然后,控制器将看到请求的图像,并从文件系统加载相应的文件。这将允许您在无需任何特殊处理的情况下执行所需操作。

如何:

routes.MapRoute("Images",
        "/images/{filename}.jpg",
        new { controller = "Image", action = "Resize" });
这应该确保只有扩展名为.jpg的URL与该路由匹配,并得到适当的路由

还请记住,您希望按从最具体到最不具体的顺序添加操作,默认操作添加在最后


当然,您的操作仍然需要使用filecontentresult提供图像

您还可以考虑:

  • 编写一个模块来处理这些映像路由,然后再点击路由(在Web.Config中注册)
  • 专门编写自己的路由处理程序来处理这些图像 这两种方法都可以让你不再需要作为一个控制器来写东西,我认为这更干净

    您自己的路由处理程序的非常基本的示例(来自内存)

    注册为正常路线:

    /* Register in routing */
    routes.Add("MyImageHandler",
               new Route("my-custom-url/{folder}/{filename}", 
               new ImageRouteHandler())
    );
    
    
    /* Your route handler */
    public class ImageRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            string filename = requestContext.RouteData.Values["filename"] as string;
            string folder = requestContext.RouteData.Values["folder"] as string;
            string width = requestContext.HttpContext.Request.Params["w"] as string;
            string height = requestContext.HttpContext.Request.Params["h"] as string;
    
            // Look up the file and handle and return, etc...
        }
    }
    

    希望这些帮助。扩展和实现的方法很多:)

    如果您提供这样的大小调整器,请注意潜在的DOS。例如,如果我请求
    image.jpg?width=100000&height=100000
    您的服务器将出现问题。谢谢您的建议。我已经解释过这样简单的拒绝服务攻击了。看起来我的触发有点太快了。似乎有一个属性可以设置,它允许您甚至为现有文件强制路由。查看我的更新答案。顺便说一句,请不要称之为MVC路由。。。路由是asp.net中的一级公民,同样适用于Webforms和MVC。除了所有良好的响应之外,我建议缓存生成的缩略图,并允许一个小的预定义大小集。我想你误解了我最初的问题。我已经创建了这个动作,现在我正试图让MVC路由到它。