【问题标题】:MVC URL routing, routes to wrong route, why?MVC URL路由,路由到错误的路由,为什么?
【发布时间】:2011-10-05 15:14:58
【问题描述】:

问题:

这是我的注册路由:

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


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


            // insert_dateti
            routes.MapRoute(
                "Default", // Routenname
                "{controller}/{action}/{id}", // URL mit Parametern
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
                //new { controller = "Home", action = "Splash", id = UrlParameter.Optional } // Parameterstandardwerte
                //new { controller = "Folders", action = "Content", id = UrlParameter.Optional } // Parameterstandardwerte
            );



        } // End Sub RegisterRoutes

这是我的路由处理程序

using System;
using System.IO;
using System.Web;
using System.Linq; 
using System.Web.UI;
using System.Web.Routing;
using System.Web.Compilation; 
using System.Collections.Generic; 


namespace HttpRuntime.Routing
{ 


    public class ImageRouteHandler : IRouteHandler 
    {


        public string MapRemoteLocation(string strPath)
        {
            if (string.IsNullOrEmpty(strPath))
                return "";

            string strBaseURL = "http://madskristensen.net/themes/standard/";
            return strBaseURL + strPath;
        }

        public IHttpHandler GetHttpHandler(RequestContext requestContext) 
        { 


            string filename = requestContext.RouteData.Values["filename"] as string; 

            if (string.IsNullOrEmpty(filename)) 
            {
                // return a 404 HttpHandler here
                requestContext.HttpContext.Response.StatusCode = 404;
                requestContext.HttpContext.Response.End();
                return null;
            } // End if (string.IsNullOrEmpty(filename)) 
            else 
            { 
                requestContext.HttpContext.Response.Clear();
                requestContext.HttpContext.Response.ContentType = GetContentType(filename);
                requestContext.HttpContext.Response.Redirect(MapRemoteLocation(filename));


                // find physical path to image here.   
                //string filepath = requestContext.HttpContext.Server.MapPath("~/test.jpg");


                // string stPath = requestContext.HttpContext.Request.Url.AbsolutePath;
                //requestContext.HttpContext.Response.WriteFile(filepath); 
                //requestContext.HttpContext.Response.End();
            } // End Else of if (string.IsNullOrEmpty(filename)) 

            return null; 
        } // End Function GetHttpHandler


        public static void MsgBox(object obj)
        {
            if (obj != null)
                System.Windows.Forms.MessageBox.Show(obj.ToString());
            else
                System.Windows.Forms.MessageBox.Show("obj is NULL");
        } // End Sub MsgBox


        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;
            } // End switch (Path.GetExtension(path))  
            return "";
        } // End Function GetContentType


    } // End Class ImageRouteHandler : IRouteHandler 


}  // End Namespace HttpRuntime.Routing

这样做的目标是,当我在 /Home/Index.cshtml 中有这个时

<img src="graphics/mads2011.png?v=123" title="Compose E-Mail" alt="Compose E-Mail" />

它从远程主机下载图片。

只要我有它就可以正常工作

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

但是当我把它改成

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

为了允许子文件夹,它会将每个 url 操作重定向到 /graphics。

例如当我有

$(function () {
        $("#divJsTreeDemo").jstree({ 
        "json_data" : {
            "ajax" : {
                 "url": "@Url.Action("GetNodesJson", "Home")"
                 //"url": "@Url.Action("GetTreeData", "Home")"
                ,"async" : true

在 Home/Index.cshtml 中

生成的 HTML 页面上 AJAX 调用的 URL 变为

"url": "/graphics?action=GetNodesJson&amp;controller=Home"

这是为什么? 我该如何解决这个问题? 如果我将我的 ImagesRoute 移动到底部,JavaScript 路由正确,但是我无法获得更多远程图像,因为它们被路由到不存在的控制器“图形”——> Exception no such view...

【问题讨论】:

  • 我非常喜欢 aspnetmvc... 我非常讨厌路由。我感觉到你的痛苦。抱歉,我帮不上忙。
  • 哦,一个可能的帮助是我在遇到路由问题时使用来自mvccontrib.codeplex.com 的路由调试器。

标签: c# asp.net-mvc asp.net-mvc-3 model-view-controller url-routing


【解决方案1】:

从路由构建链接时,使用{*filename}ImagesRoute 将满足所有条件,因此如果路由表中位于Default 路由之前,则该路由将始终用于构建链接。但是,在处理请求时,它会按预期工作,因为 ImagesRoute 路由只会被以 http://mysite.com/graphics/... 开头的请求满足

为了解决这个问题,您需要将 ImagesRoutes 移动到默认路由下方,然后您需要在默认路由中添加一个RouteConstraint,这样任何以graphics 开头的请求都会失败默认路由。

如下更改您的默认路由:

routes.MapRoute(
    "Default", // Routenname
    "{controller}/{action}/{id}", // URL mit Parametern
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults
    new { controller = @"^(?!graphics).+" } // constraint
);

【讨论】:

  • 太好了,工作!非常感谢你 !虽然我必须说我仍然不明白为什么 @Url.Action("GetNodesJson", "Home")" 是 /Home/GetNodesJson 满足 /graphics/whatever。或者为什么 @Url.Action("ActionName", " ControllerName") 变成 graphics/controllername/ActionName。不知何故,我猜它只是将扩展的 route2 填充到 route1 中......我想我必须阅读 MVC 的源代码才能理解该路由部分。
  • 因为您的 ImagesRoute URL 参数由一个贪心匹配组成,它匹配 MVC 构建的任何链接。在链接建设方面,一切都与该路线相匹配。请标记为已回答。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 2012-01-09
  • 2017-09-25
相关资源
最近更新 更多